From 3c9204c3effe7e2c376a51c7a4c7a29a3da437ba Mon Sep 17 00:00:00 2001 From: NickDollahZ Date: Thu, 17 Oct 2013 08:01:05 -0700 Subject: First Commit of N5100 device files --- Android.mk | 23 + AndroidProducts.mk | 18 + BoardConfig.mk | 66 + LICENSE | 191 + README | 10 + README.md | 4 + audio/Android.mk | 33 + audio/audio_hw.c | 3027 ++++++++++++++ audio/audio_hw.h | 239 ++ audio/ril_interface.c | 183 + audio/ril_interface.h | 72 + bluetooth/bdroid_buildcfg.h | 36 + bluetooth/vnd_n5100.txt | 14 + camera/Android.mk | 54 + camera/MODULE_LICENSE_GPL | 0 camera/NOTICE | 674 ++++ camera/exynos_camera.c | 4033 +++++++++++++++++++ camera/exynos_camera.h | 680 ++++ camera/exynos_exif.c | 873 ++++ camera/exynos_ion.c | 159 + camera/exynos_jpeg.c | 404 ++ camera/exynos_param.c | 492 +++ camera/exynos_utils.c | 158 + camera/exynos_v4l2.c | 739 ++++ camera/exynos_v4l2_output.c | 394 ++ camera/include/linux/fimc.h | 381 ++ camera/include/linux/ion.h | 449 +++ camera/include/linux/videodev2.h | 2364 +++++++++++ camera/include/linux/videodev2_exynos_camera.h | 2047 ++++++++++ camera/include/linux/videodev2_exynos_media.h | 225 ++ cm.dependencies | 18 + cm.mk | 21 + configs/Android.mk | 12 + configs/gps.xml | 72 + configs/nvram_mfg.txt | 146 + configs/nvram_mfg.txt_murata | 145 + configs/nvram_net.txt | 152 + configs/nvram_net.txt_murata | 155 + configs/tiny_hw.xml | 340 ++ extract-files.sh | 105 + full_n5100.mk | 35 + include/hardware/gps.h | 949 +++++ include/telephony/ril.h | 4252 ++++++++++++++++++++ irda/Android.mk | 13 + irda/irda.c | 75 + libsensors/AccelSensor.cpp | 176 + libsensors/AccelSensor.h | 69 + libsensors/Android.mk | 47 + libsensors/CompassSensor.cpp | 190 + libsensors/CompassSensor.h | 54 + libsensors/InputEventReader.cpp | 88 + libsensors/InputEventReader.h | 47 + libsensors/LightSensor.cpp | 145 + libsensors/LightSensor.h | 54 + libsensors/OrientationSensor.cpp | 184 + libsensors/OrientationSensor.h | 54 + libsensors/ProximitySensor.cpp | 144 + libsensors/ProximitySensor.h | 54 + libsensors/SensorBase.cpp | 128 + libsensors/SensorBase.h | 65 + libsensors/sensors.cpp | 374 ++ libsensors/sensors.h | 119 + n5100.mk | 87 + .../frameworks/base/core/res/res/values/config.xml | 107 + .../base/core/res/res/values/config.xml~ | 104 + .../base/core/res/res/xml/power_profile.xml | 61 + .../base/core/res/res/xml/storage_list.xml | 51 + overlay/packages/apps/Browser/res/values/bools.xml | 16 + overlay/packages/apps/Camera/res/values/config.xml | 23 + .../packages/apps/Launcher2/res/values/config.xml | 18 + .../packages/apps/Settings/res/values/arrays.xml | 46 + .../packages/apps/Settings/res/values/bools.xml | 23 + .../packages/apps/Settings/res/values/config.xml | 20 + .../packages/apps/SystemUI/res/values/config.xml | 26 + overlay/packages/apps/Torch/res/values/config.xml | 36 + proprietary-files.txt | 3 + rootdir/fstab.smdk4x12 | 19 + rootdir/init.smdk4x12.rc | 592 +++ rootdir/init.smdk4x12.usb.rc | 134 + rootdir/lpm.rc | 82 + rootdir/ueventd.smdk4x12.rc | 83 + secril_multi/Oem_ril_sap.h | 284 ++ system.prop | 12 + twrp.fstab | 12 + 84 files changed, 28363 insertions(+) create mode 100644 Android.mk create mode 100644 AndroidProducts.mk create mode 100755 BoardConfig.mk create mode 100644 LICENSE create mode 100644 README create mode 100644 README.md create mode 100644 audio/Android.mk create mode 100755 audio/audio_hw.c create mode 100644 audio/audio_hw.h create mode 100755 audio/ril_interface.c create mode 100755 audio/ril_interface.h create mode 100755 bluetooth/bdroid_buildcfg.h create mode 100755 bluetooth/vnd_n5100.txt create mode 100644 camera/Android.mk create mode 100644 camera/MODULE_LICENSE_GPL create mode 100644 camera/NOTICE create mode 100755 camera/exynos_camera.c create mode 100755 camera/exynos_camera.h create mode 100644 camera/exynos_exif.c create mode 100644 camera/exynos_ion.c create mode 100644 camera/exynos_jpeg.c create mode 100644 camera/exynos_param.c create mode 100644 camera/exynos_utils.c create mode 100644 camera/exynos_v4l2.c create mode 100644 camera/exynos_v4l2_output.c create mode 100644 camera/include/linux/fimc.h create mode 100644 camera/include/linux/ion.h create mode 100644 camera/include/linux/videodev2.h create mode 100644 camera/include/linux/videodev2_exynos_camera.h create mode 100644 camera/include/linux/videodev2_exynos_media.h create mode 100644 cm.dependencies create mode 100644 cm.mk create mode 100644 configs/Android.mk create mode 100755 configs/gps.xml create mode 100755 configs/nvram_mfg.txt create mode 100755 configs/nvram_mfg.txt_murata create mode 100755 configs/nvram_net.txt create mode 100755 configs/nvram_net.txt_murata create mode 100755 configs/tiny_hw.xml create mode 100755 extract-files.sh create mode 100644 full_n5100.mk create mode 100755 include/hardware/gps.h create mode 100644 include/telephony/ril.h create mode 100644 irda/Android.mk create mode 100644 irda/irda.c create mode 100644 libsensors/AccelSensor.cpp create mode 100644 libsensors/AccelSensor.h create mode 100644 libsensors/Android.mk create mode 100644 libsensors/CompassSensor.cpp create mode 100644 libsensors/CompassSensor.h create mode 100644 libsensors/InputEventReader.cpp create mode 100644 libsensors/InputEventReader.h create mode 100644 libsensors/LightSensor.cpp create mode 100644 libsensors/LightSensor.h create mode 100644 libsensors/OrientationSensor.cpp create mode 100644 libsensors/OrientationSensor.h create mode 100644 libsensors/ProximitySensor.cpp create mode 100644 libsensors/ProximitySensor.h create mode 100644 libsensors/SensorBase.cpp create mode 100644 libsensors/SensorBase.h create mode 100644 libsensors/sensors.cpp create mode 100644 libsensors/sensors.h create mode 100755 n5100.mk create mode 100755 overlay/frameworks/base/core/res/res/values/config.xml create mode 100755 overlay/frameworks/base/core/res/res/values/config.xml~ create mode 100644 overlay/frameworks/base/core/res/res/xml/power_profile.xml create mode 100644 overlay/frameworks/base/core/res/res/xml/storage_list.xml create mode 100644 overlay/packages/apps/Browser/res/values/bools.xml create mode 100644 overlay/packages/apps/Camera/res/values/config.xml create mode 100644 overlay/packages/apps/Launcher2/res/values/config.xml create mode 100644 overlay/packages/apps/Settings/res/values/arrays.xml create mode 100644 overlay/packages/apps/Settings/res/values/bools.xml create mode 100644 overlay/packages/apps/Settings/res/values/config.xml create mode 100755 overlay/packages/apps/SystemUI/res/values/config.xml create mode 100644 overlay/packages/apps/Torch/res/values/config.xml create mode 100644 proprietary-files.txt create mode 100644 rootdir/fstab.smdk4x12 create mode 100755 rootdir/init.smdk4x12.rc create mode 100755 rootdir/init.smdk4x12.usb.rc create mode 100644 rootdir/lpm.rc create mode 100644 rootdir/ueventd.smdk4x12.rc create mode 100755 secril_multi/Oem_ril_sap.h create mode 100755 system.prop create mode 100644 twrp.fstab diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..8650675 --- /dev/null +++ b/Android.mk @@ -0,0 +1,23 @@ +# +# Copyright (C) 2012 The CyanogenMod 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) + +ifeq ($(TARGET_DEVICE),n5100) + +include $(call all-makefiles-under,$(LOCAL_PATH)) + +endif diff --git a/AndroidProducts.mk b/AndroidProducts.mk new file mode 100644 index 0000000..2aee4a7 --- /dev/null +++ b/AndroidProducts.mk @@ -0,0 +1,18 @@ +# +# Copyright (C) 2012 The CyanogenMod 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)/full_n5100.mk diff --git a/BoardConfig.mk b/BoardConfig.mk new file mode 100755 index 0000000..4e8d0a6 --- /dev/null +++ b/BoardConfig.mk @@ -0,0 +1,66 @@ +# +# Copyright (C) 2012 The CyanogenMod 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. +# + +# This variable is set first, so it can be overridden +# by BoardConfigVendor.mk +-include device/samsung/smdk4412-common/BoardCommonConfig.mk + +LOCAL_PATH := device/samsung/n5100 + +# Bluetooth +BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := $(LOCAL_PATH)/bluetooth +BOARD_BLUEDROID_VENDOR_CONF := device/samsung/n5100/bluetooth/vnd_n5100.txt + +# Inline kernel building +TARGET_KERNEL_SOURCE := kernel/samsung/smdk4412 +TARGET_KERNEL_CONFIG := cyanogenmod_n5100_defconfig + +# Camera +COMMON_GLOBAL_CFLAGS += -DCAMERA_WITH_CITYID_PARAM + +# Sensors +BOARD_USE_LEGACY_SENSORS_FUSION = false + +TARGET_SPECIFIC_HEADER_PATH := $(LOCAL_PATH)/include + +# Charging mode +BOARD_CHARGING_MODE_BOOTING_LPM := /sys/class/power_supply/battery/batt_lp_charging +BOARD_BATTERY_DEVICE_NAME := "battery" +BOARD_CHARGER_RES := device/samsung/n5100/res/charger# RIL +BOARD_PROVIDES_LIBRIL := true +BOARD_MODEM_TYPE := xmm6262 + +# Recovery +TARGET_RECOVERY_FSTAB := device/samsung/n5100/rootdir/fstab.smdk4x12 +RECOVERY_FSTAB_VERSION := 2 + +#TWRP FLAGS +DEVICE_RESOLUTION := 1280x800 +RECOVERY_SDCARD_ON_DATA := true +TW_INTERNAL_STORAGE_PATH := "/data/media" +TW_INTERNAL_STORAGE_MOUNT_POINT := "data" +TW_EXTERNAL_STORAGE_PATH := "/external_sdcard" +TW_EXTERNAL_STORAGE_MOUNT_POINT := "external_sdcard" +TW_BRIGHTNESS_PATH := "/sys/class/backlight/panel/brightness" +BOARD_HAS_NO_REAL_SDCARD := true +TARGET_USERIMAGES_USE_EXT4 := true +TW_NO_USB_STORAGE := true + +# inherit from the proprietary version +-include vendor/samsung/n5100/BoardConfigVendor.mk + +# assert +TARGET_OTA_ASSERT_DEVICE := kona3gxx,n5100,GT-N5100,kona3g diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..37ec93a --- /dev/null +++ b/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README b/README new file mode 100644 index 0000000..b8cb680 --- /dev/null +++ b/README @@ -0,0 +1,10 @@ +Device configuration for the Samsung Galaxy Note 8.0 (3G) +GT-N5100 + +Copyright (C) 2013 The CyanogenMod 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 diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ac87a9 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +android_device_samsung_n5100 +============================ + +Galaxy Note 8 International Version GT-N5100 diff --git a/audio/Android.mk b/audio/Android.mk new file mode 100644 index 0000000..4655db0 --- /dev/null +++ b/audio/Android.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2011 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 := audio.primary.$(TARGET_BOOTLOADER_BOARD_NAME) +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := audio_hw.c ril_interface.c + +LOCAL_C_INCLUDES += \ + external/tinyalsa/include \ + external/expat/lib \ + $(call include-path-for, audio-utils) \ + $(call include-path-for, audio-effects) + +LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioutils libdl libexpat + +include $(BUILD_SHARED_LIBRARY) diff --git a/audio/audio_hw.c b/audio/audio_hw.c new file mode 100755 index 0000000..e4f5edf --- /dev/null +++ b/audio/audio_hw.c @@ -0,0 +1,3027 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2012 Wolfson Microelectronics plc + * Copyright (C) 2012 The CyanogenMod Project + * Daniel Hillenbrand + * Guillaume "XpLoDWilD" Lesniak + * + * 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_primary" +#define LOG_NDEBUG 0 + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "audio_hw.h" +#include "ril_interface.h" + +struct pcm_config pcm_config_mm = { + .channels = 2, + .rate = MM_FULL_POWER_SAMPLING_RATE, + .period_size = DEEP_BUFFER_LONG_PERIOD_SIZE, + .period_count = PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT, + .format = PCM_FORMAT_S16_LE, +}; + +struct pcm_config pcm_config_tones = { + .channels = 2, + .rate = MM_FULL_POWER_SAMPLING_RATE, + .period_size = SHORT_PERIOD_SIZE, + .period_count = PLAYBACK_SHORT_PERIOD_COUNT, + .format = PCM_FORMAT_S16_LE, + .start_threshold = 0, + .avail_min = 0, +}; + +struct pcm_config pcm_config_capture = { + .channels = 2, + .rate = DEFAULT_IN_SAMPLING_RATE, + .period_size = CAPTURE_PERIOD_SIZE, + .period_count = CAPTURE_PERIOD_COUNT, + .format = PCM_FORMAT_S16_LE, +}; + +struct pcm_config pcm_config_vx = { + .channels = 2, + .rate = VX_NB_SAMPLING_RATE, + .period_size = 160, + .period_count = 2, + .format = PCM_FORMAT_S16_LE, +}; + +#define MIN(x, y) ((x) > (y) ? (y) : (x)) + +struct m0_audio_device { + struct audio_hw_device hw_device; + + pthread_mutex_t lock; /* see note below on mutex acquisition order */ + struct m0_dev_cfg *dev_cfgs; + int num_dev_cfgs; + struct mixer *mixer; + struct mixer_ctls mixer_ctls; + audio_mode_t mode; + int active_out_device; + int out_device; + int active_in_device; + int in_device; + struct pcm *pcm_modem_dl; + struct pcm *pcm_modem_ul; + int in_call; + float voice_volume; + struct m0_stream_in *active_input; + struct m0_stream_out *outputs[OUTPUT_TOTAL]; + bool mic_mute; + int tty_mode; + struct echo_reference_itfe *echo_reference; + bool bluetooth_nrec; + int wb_amr; + bool screen_off; + + /* RIL */ + struct ril_handle ril; +}; + +struct m0_stream_out { + struct audio_stream_out stream; + + pthread_mutex_t lock; /* see note below on mutex acquisition order */ + struct pcm_config config[PCM_TOTAL]; + struct pcm *pcm[PCM_TOTAL]; + struct resampler_itfe *resampler; + char *buffer; + size_t buffer_frames; + int standby; + struct echo_reference_itfe *echo_reference; + int write_threshold; + bool use_long_periods; + audio_channel_mask_t channel_mask; + audio_channel_mask_t sup_channel_masks[3]; + + struct m0_audio_device *dev; +}; + +#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */ + +struct effect_info_s { + effect_handle_t effect_itfe; + size_t num_channel_configs; + channel_config_t* channel_configs; +}; + +#define NUM_IN_AUX_CNL_CONFIGS 2 +channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = { + { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK}, + { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT} +}; + +struct m0_stream_in { + struct audio_stream_in stream; + + pthread_mutex_t lock; /* see note below on mutex acquisition order */ + struct pcm_config config; + struct pcm *pcm; + int device; + struct resampler_itfe *resampler; + struct resampler_buffer_provider buf_provider; + unsigned int requested_rate; + int standby; + int source; + struct echo_reference_itfe *echo_reference; + bool need_echo_reference; + + int16_t *read_buf; + size_t read_buf_size; + size_t read_buf_frames; + + int16_t *proc_buf_in; + int16_t *proc_buf_out; + size_t proc_buf_size; + size_t proc_buf_frames; + + int16_t *ref_buf; + size_t ref_buf_size; + size_t ref_buf_frames; + + int read_status; + + int num_preprocessors; + struct effect_info_s preprocessors[MAX_PREPROCESSORS]; + + bool aux_channels_changed; + uint32_t main_channels; + uint32_t aux_channels; + struct m0_audio_device *dev; +}; + +struct m0_dev_cfg { + int mask; + + struct route_setting *on; + unsigned int on_len; + + struct route_setting *off; + unsigned int off_len; +}; + +/** + * NOTE: when multiple mutexes have to be acquired, always respect the following order: + * hw device > in stream > out stream + */ + +static void select_output_device(struct m0_audio_device *adev); +static void select_input_device(struct m0_audio_device *adev); +static int adev_set_voice_volume(struct audio_hw_device *dev, float volume); +static int do_input_standby(struct m0_stream_in *in); +static int do_output_standby(struct m0_stream_out *out); +static void in_update_aux_channels(struct m0_stream_in *in, effect_handle_t effect); + +/* The enable flag when 0 makes the assumption that enums are disabled by + * "Off" and integers/booleans by 0 */ +static int set_bigroute_by_array(struct mixer *mixer, struct route_setting *route, + int enable) +{ + struct mixer_ctl *ctl; + unsigned int i, j, ret; + + /* Go through the route array and set each value */ + i = 0; + while (route[i].ctl_name) { + ctl = mixer_get_ctl_by_name(mixer, route[i].ctl_name); + if (!ctl) { + ALOGE("Unknown control '%s'\n", route[i].ctl_name); + return -EINVAL; + } + + if (route[i].strval) { + if (enable) { + ret = mixer_ctl_set_enum_by_string(ctl, route[i].strval); + if (ret != 0) { + ALOGE("Failed to set '%s' to '%s'\n", route[i].ctl_name, route[i].strval); + } else { + ALOGV("Set '%s' to '%s'\n", route[i].ctl_name, route[i].strval); + } + } else { + ret = mixer_ctl_set_enum_by_string(ctl, "Off"); + if (ret != 0) { + ALOGE("Failed to set '%s' to '%s'\n", route[i].ctl_name, route[i].strval); + } else { + ALOGV("Set '%s' to '%s'\n", route[i].ctl_name, "Off"); + } + } + } else { + /* This ensures multiple (i.e. stereo) values are set jointly */ + for (j = 0; j < mixer_ctl_get_num_values(ctl); j++) { + if (enable) { + ret = mixer_ctl_set_value(ctl, j, route[i].intval); + if (ret != 0) { + ALOGE("Failed to set '%s' to '%d'\n", route[i].ctl_name, route[i].intval); + } else { + ALOGV("Set '%s' to '%d'\n", route[i].ctl_name, route[i].intval); + } + } else { + ret = mixer_ctl_set_value(ctl, j, 0); + if (ret != 0) { + ALOGE("Failed to set '%s' to '%d'\n", route[i].ctl_name, route[i].intval); + } else { + ALOGV("Set '%s' to '%d'\n", route[i].ctl_name, 0); + } + } + } + } + i++; + } + + return 0; +} + +/* The enable flag when 0 makes the assumption that enums are disabled by + * "Off" and integers/booleans by 0 */ +static int set_route_by_array(struct mixer *mixer, struct route_setting *route, + unsigned int len) +{ + struct mixer_ctl *ctl; + unsigned int i, j, ret; + + /* Go through the route array and set each value */ + for (i = 0; i < len; i++) { + ctl = mixer_get_ctl_by_name(mixer, route[i].ctl_name); + if (!ctl) { + ALOGE("Unknown control '%s'\n", route[i].ctl_name); + return -EINVAL; + } + + if (route[i].strval) { + ret = mixer_ctl_set_enum_by_string(ctl, route[i].strval); + if (ret != 0) { + ALOGE("Failed to set '%s' to '%s'\n", + route[i].ctl_name, route[i].strval); + } else { + ALOGV("Set '%s' to '%s'\n", + route[i].ctl_name, route[i].strval); + } + + } else { + /* This ensures multiple (i.e. stereo) values are set jointly */ + for (j = 0; j < mixer_ctl_get_num_values(ctl); j++) { + ret = mixer_ctl_set_value(ctl, j, route[i].intval); + if (ret != 0) { + ALOGE("Failed to set '%s'.%d to %d\n", + route[i].ctl_name, j, route[i].intval); + } else { + ALOGV("Set '%s'.%d to %d\n", + route[i].ctl_name, j, route[i].intval); + } + } + } + } + + return 0; +} + +/* Must be called with lock */ +void select_devices(struct m0_audio_device *adev) +{ + int i; + + if (adev->active_out_device == adev->out_device && adev->active_in_device == adev->in_device) + return; + + ALOGV("Changing output device %x => %x\n", adev->active_out_device, adev->out_device); + ALOGV("Changing input device %x => %x\n", adev->active_in_device, adev->in_device); + + /* Turn on new devices first so we don't glitch due to powerdown... */ + for (i = 0; i < adev->num_dev_cfgs; i++) + if ((adev->out_device & adev->dev_cfgs[i].mask) && + !(adev->active_out_device & adev->dev_cfgs[i].mask)) + set_route_by_array(adev->mixer, adev->dev_cfgs[i].on, + adev->dev_cfgs[i].on_len); + + for (i = 0; i < adev->num_dev_cfgs; i++) + if ((adev->in_device & adev->dev_cfgs[i].mask) && + !(adev->active_in_device & adev->dev_cfgs[i].mask)) + set_route_by_array(adev->mixer, adev->dev_cfgs[i].on, + adev->dev_cfgs[i].on_len); + + /* ...then disable old ones. */ + for (i = 0; i < adev->num_dev_cfgs; i++) + if (!(adev->out_device & adev->dev_cfgs[i].mask) && + (adev->active_out_device & adev->dev_cfgs[i].mask)) + set_route_by_array(adev->mixer, adev->dev_cfgs[i].off, + adev->dev_cfgs[i].off_len); + + for (i = 0; i < adev->num_dev_cfgs; i++) + if (!(adev->in_device & adev->dev_cfgs[i].mask) && + (adev->active_in_device & adev->dev_cfgs[i].mask)) + set_route_by_array(adev->mixer, adev->dev_cfgs[i].off, + adev->dev_cfgs[i].off_len); + + adev->active_out_device = adev->out_device; + adev->active_in_device = adev->in_device; +} + +static int start_call(struct m0_audio_device *adev) +{ + ALOGE("Opening modem PCMs"); + int bt_on; + + bt_on = adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO; + pcm_config_vx.rate = adev->wb_amr ? VX_WB_SAMPLING_RATE : VX_NB_SAMPLING_RATE; + + /* Open modem PCM channels */ + if (adev->pcm_modem_dl == NULL) { + if (bt_on) + adev->pcm_modem_dl = pcm_open(CARD_DEFAULT, PORT_BT, PCM_OUT, &pcm_config_vx); + else + adev->pcm_modem_dl = pcm_open(CARD_DEFAULT, PORT_MODEM, PCM_OUT, &pcm_config_vx); + if (!pcm_is_ready(adev->pcm_modem_dl)) { + ALOGE("cannot open PCM modem DL stream: %s", pcm_get_error(adev->pcm_modem_dl)); + goto err_open_dl; + } + } + + if (adev->pcm_modem_ul == NULL) { + adev->pcm_modem_ul = pcm_open(CARD_DEFAULT, PORT_MODEM, PCM_IN, &pcm_config_vx); + if (!pcm_is_ready(adev->pcm_modem_ul)) { + ALOGE("cannot open PCM modem UL stream: %s", pcm_get_error(adev->pcm_modem_ul)); + goto err_open_ul; + } + } + + pcm_start(adev->pcm_modem_dl); + pcm_start(adev->pcm_modem_ul); + + return 0; + +err_open_ul: + pcm_close(adev->pcm_modem_ul); + adev->pcm_modem_ul = NULL; +err_open_dl: + pcm_close(adev->pcm_modem_dl); + adev->pcm_modem_dl = NULL; + + return -ENOMEM; +} + +static void end_call(struct m0_audio_device *adev) +{ + ALOGE("Closing modem PCMs"); + pcm_stop(adev->pcm_modem_dl); + pcm_stop(adev->pcm_modem_ul); + pcm_close(adev->pcm_modem_dl); + pcm_close(adev->pcm_modem_ul); + adev->pcm_modem_dl = NULL; + adev->pcm_modem_ul = NULL; + + /* re-enable +30db boost on mics */ + mixer_ctl_set_value(adev->mixer_ctls.mixinl_in1l_volume, 0, 1); + mixer_ctl_set_value(adev->mixer_ctls.mixinl_in2l_volume, 0, 1); +} + +static void set_eq_filter(struct m0_audio_device *adev) +{ +} + +void audio_set_wb_amr_callback(void *data, int enable) +{ + struct m0_audio_device *adev = (struct m0_audio_device *)data; + + pthread_mutex_lock(&adev->lock); + if (adev->wb_amr != enable) { + adev->wb_amr = enable; + + /* reopen the modem PCMs at the new rate */ + if (adev->in_call) { + end_call(adev); + select_output_device(adev); + start_call(adev); + } + } + pthread_mutex_unlock(&adev->lock); +} + +static void set_incall_device(struct m0_audio_device *adev) +{ + int device_type; + + switch(adev->out_device) { + case AUDIO_DEVICE_OUT_EARPIECE: + device_type = SOUND_AUDIO_PATH_HANDSET; + break; + case AUDIO_DEVICE_OUT_SPEAKER: + case AUDIO_DEVICE_OUT_AUX_DIGITAL: + case AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET: + device_type = SOUND_AUDIO_PATH_SPEAKER; + break; + case AUDIO_DEVICE_OUT_WIRED_HEADSET: + device_type = SOUND_AUDIO_PATH_HEADSET; + break; + case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: + device_type = SOUND_AUDIO_PATH_HEADPHONE; + break; + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: + case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: + if (adev->bluetooth_nrec) { + device_type = SOUND_AUDIO_PATH_BLUETOOTH; + } else { + device_type = SOUND_AUDIO_PATH_BLUETOOTH_NO_NR; + } + break; + default: + device_type = SOUND_AUDIO_PATH_HANDSET; + break; + } + + /* if output device isn't supported, open modem side to handset by default */ + ALOGE("%s: ril_set_call_audio_path(%d)", __func__, device_type); + ril_set_call_audio_path(&adev->ril, device_type); +} + +static void set_input_volumes(struct m0_audio_device *adev, int main_mic_on, + int headset_mic_on, int sub_mic_on) +{ +} + +static void set_output_volumes(struct m0_audio_device *adev, bool tty_volume) +{ +} + +static void force_all_standby(struct m0_audio_device *adev) +{ + struct m0_stream_in *in; + struct m0_stream_out *out; + + /* only needed for low latency output streams as other streams are not used + * for voice use cases */ + if (adev->outputs[OUTPUT_LOW_LATENCY] != NULL && + !adev->outputs[OUTPUT_LOW_LATENCY]->standby) { + out = adev->outputs[OUTPUT_LOW_LATENCY]; + pthread_mutex_lock(&out->lock); + do_output_standby(out); + pthread_mutex_unlock(&out->lock); + } + + if (adev->active_input) { + in = adev->active_input; + pthread_mutex_lock(&in->lock); + do_input_standby(in); + pthread_mutex_unlock(&in->lock); + } +} + +static void select_mode(struct m0_audio_device *adev) +{ + if (adev->mode == AUDIO_MODE_IN_CALL) { + ALOGE("Entering IN_CALL state, in_call=%d", adev->in_call); + if (!adev->in_call) { + force_all_standby(adev); + /* force earpiece route for in call state if speaker is the + only currently selected route. This prevents having to tear + down the modem PCMs to change route from speaker to earpiece + after the ringtone is played, but doesn't cause a route + change if a headset or bt device is already connected. If + speaker is not the only thing active, just remove it from + the route. We'll assume it'll never be used initally during + a call. This works because we're sure that the audio policy + manager will update the output device after the audio mode + change, even if the device selection did not change. */ + if (adev->out_device == AUDIO_DEVICE_OUT_SPEAKER) { + adev->out_device = AUDIO_DEVICE_OUT_EARPIECE; + adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; + } else + adev->out_device &= ~AUDIO_DEVICE_OUT_SPEAKER; + select_output_device(adev); + start_call(adev); + ril_set_call_clock_sync(&adev->ril, SOUND_CLOCK_START); + adev_set_voice_volume(&adev->hw_device, adev->voice_volume); + adev->in_call = 1; + } + } else { + ALOGE("Leaving IN_CALL state, in_call=%d, mode=%d", + adev->in_call, adev->mode); + if (adev->in_call) { + adev->in_call = 0; + end_call(adev); + force_all_standby(adev); + select_output_device(adev); + select_input_device(adev); + } + } +} + +static void select_output_device(struct m0_audio_device *adev) +{ + int headset_on; + int headphone_on; + int speaker_on; + int earpiece_on; + int bt_on; + bool tty_volume = false; + unsigned int channel; + + headset_on = adev->out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET; + headphone_on = adev->out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; + speaker_on = adev->out_device & AUDIO_DEVICE_OUT_SPEAKER; + earpiece_on = adev->out_device & AUDIO_DEVICE_OUT_EARPIECE; + bt_on = adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO; + + switch(adev->out_device) { + case AUDIO_DEVICE_OUT_SPEAKER: + ALOGD("%s: AUDIO_DEVICE_OUT_SPEAKER", __func__); + break; + case AUDIO_DEVICE_OUT_WIRED_HEADSET: + ALOGD("%s: AUDIO_DEVICE_OUT_WIRED_HEADSET", __func__); + break; + case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: + ALOGD("%s: AUDIO_DEVICE_OUT_WIRED_HEADPHONE", __func__); + break; + case AUDIO_DEVICE_OUT_EARPIECE: + ALOGD("%s: AUDIO_DEVICE_OUT_EARPIECE", __func__); + break; + case AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET: + ALOGD("%s: AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET", __func__); + break; + case AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET: + ALOGD("%s: AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET", __func__); + break; + case AUDIO_DEVICE_OUT_ALL_SCO: + ALOGD("%s: AUDIO_DEVICE_OUT_ALL_SCO", __func__); + break; + default: + ALOGD("%s: AUDIO_DEVICE_OUT_ALL", __func__); + break; + } + + select_devices(adev); + + set_eq_filter(adev); + + if (adev->mode == AUDIO_MODE_IN_CALL) { + if (!bt_on) { + /* force tx path according to TTY mode when in call */ + switch(adev->tty_mode) { + case TTY_MODE_FULL: + case TTY_MODE_HCO: + /* tx path from headset mic */ + headphone_on = 0; + headset_on = 1; + speaker_on = 0; + earpiece_on = 0; + break; + case TTY_MODE_VCO: + /* tx path from device sub mic */ + headphone_on = 0; + headset_on = 0; + speaker_on = 1; + earpiece_on = 0; + break; + case TTY_MODE_OFF: + default: + break; + } + } + + if (headset_on || headphone_on || speaker_on || earpiece_on) { + ALOGD("%s: set voicecall route: voicecall_default", __func__); + set_bigroute_by_array(adev->mixer, voicecall_default, 1); + } else { + ALOGD("%s: set voicecall route: voicecall_default_disable", __func__); + set_bigroute_by_array(adev->mixer, voicecall_default_disable, 1); + } + + if (speaker_on || earpiece_on || headphone_on) { + ALOGD("%s: set voicecall route: default_input", __func__); + set_bigroute_by_array(adev->mixer, default_input, 1); + } else { + ALOGD("%s: set voicecall route: default_input_disable", __func__); + set_bigroute_by_array(adev->mixer, default_input_disable, 1); + } + + if (headset_on) { + ALOGD("%s: set voicecall route: headset_input", __func__); + set_bigroute_by_array(adev->mixer, headset_input, 1); + } else { + ALOGD("%s: set voicecall route: headset_input_disable", __func__); + set_bigroute_by_array(adev->mixer, headset_input_disable, 1); + } + + if (bt_on) { + // bt uses a different port (PORT_BT) for playback, reopen the pcms + end_call(adev); + start_call(adev); + ALOGD("%s: set voicecall route: bt_input", __func__); + set_bigroute_by_array(adev->mixer, bt_input, 1); + ALOGD("%s: set voicecall route: bt_output", __func__); + set_bigroute_by_array(adev->mixer, bt_output, 1); + } else { + ALOGD("%s: set voicecall route: bt_disable", __func__); + set_bigroute_by_array(adev->mixer, bt_disable, 1); + } + + set_incall_device(adev); + } +} + +static void select_input_device(struct m0_audio_device *adev) +{ + switch(adev->in_device) { + case AUDIO_DEVICE_IN_BUILTIN_MIC: + ALOGD("%s: AUDIO_DEVICE_IN_BUILTIN_MIC", __func__); + break; + case AUDIO_DEVICE_IN_BACK_MIC: + ALOGD("%s: AUDIO_DEVICE_IN_BACK_MIC", __func__); + break; + case AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET: + ALOGD("%s: AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET", __func__); + break; + case AUDIO_DEVICE_IN_WIRED_HEADSET: + ALOGD("%s: AUDIO_DEVICE_IN_WIRED_HEADSET", __func__); + break; + default: + break; + } + + select_devices(adev); +} + +/* must be called with hw device and output stream mutexes locked */ +static int start_output_stream_low_latency(struct m0_stream_out *out) +{ + struct m0_audio_device *adev = out->dev; + unsigned int flags = PCM_OUT; + int i; + bool success = true; + + if (adev->mode != AUDIO_MODE_IN_CALL) { + select_output_device(adev); + } + + /* default to low power: will be corrected in out_write if necessary before first write to + * tinyalsa. + */ + + if (adev->out_device & ~(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | AUDIO_DEVICE_OUT_AUX_DIGITAL)) { + /* Something not a dock in use */ + out->config[PCM_NORMAL] = pcm_config_tones; + out->config[PCM_NORMAL].rate = MM_FULL_POWER_SAMPLING_RATE; + out->pcm[PCM_NORMAL] = pcm_open(CARD_DEFAULT, PORT_PLAYBACK, + flags, &out->config[PCM_NORMAL]); + } + + if (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) { + /* SPDIF output in use */ + out->config[PCM_SPDIF] = pcm_config_tones; + out->config[PCM_SPDIF].rate = MM_FULL_POWER_SAMPLING_RATE; + out->pcm[PCM_SPDIF] = pcm_open(CARD_DEFAULT, PORT_PLAYBACK, + flags, &out->config[PCM_SPDIF]); + } + + /* Close any PCMs that could not be opened properly and return an error */ + for (i = 0; i < PCM_TOTAL; i++) { + if (out->pcm[i] && !pcm_is_ready(out->pcm[i])) { + ALOGE("%s: cannot open pcm_out driver %d: %s", __func__ , i, pcm_get_error(out->pcm[i])); + pcm_close(out->pcm[i]); + out->pcm[i] = NULL; + success = false; + } + } + + if (success) { + out->buffer_frames = pcm_config_tones.period_size * 2; + if (out->buffer == NULL) + out->buffer = malloc(out->buffer_frames * audio_stream_frame_size(&out->stream.common)); + + if (adev->echo_reference != NULL) + out->echo_reference = adev->echo_reference; + out->resampler->reset(out->resampler); + + return 0; + } + + return -ENOMEM; +} + +/* must be called with hw device and output stream mutexes locked */ +static int start_output_stream_deep_buffer(struct m0_stream_out *out) +{ + struct m0_audio_device *adev = out->dev; + + if (adev->mode != AUDIO_MODE_IN_CALL) { + select_output_device(adev); + } + + out->write_threshold = PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT * DEEP_BUFFER_LONG_PERIOD_SIZE; + out->use_long_periods = true; + + out->config[PCM_NORMAL] = pcm_config_mm; + out->config[PCM_NORMAL].rate = MM_FULL_POWER_SAMPLING_RATE; + out->pcm[PCM_NORMAL] = pcm_open(CARD_DEFAULT, PORT_PLAYBACK, + PCM_OUT | PCM_MMAP | PCM_NOIRQ, &out->config[PCM_NORMAL]); + if (out->pcm[PCM_NORMAL] && !pcm_is_ready(out->pcm[PCM_NORMAL])) { + ALOGE("%s: cannot open pcm_out driver: %s", __func__, pcm_get_error(out->pcm[PCM_NORMAL])); + pcm_close(out->pcm[PCM_NORMAL]); + out->pcm[PCM_NORMAL] = NULL; + return -ENOMEM; + } + out->buffer_frames = DEEP_BUFFER_SHORT_PERIOD_SIZE * 2; + if (out->buffer == NULL) + out->buffer = malloc(PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT * DEEP_BUFFER_LONG_PERIOD_SIZE); + + return 0; +} + +static int check_input_parameters(uint32_t sample_rate, audio_format_t format, int channel_count) +{ + if (format != AUDIO_FORMAT_PCM_16_BIT) + return -EINVAL; + + if ((channel_count < 1) || (channel_count > 2)) + return -EINVAL; + + switch(sample_rate) { + case 8000: + case 11025: + case 16000: + case 22050: + case 24000: + case 32000: + case 44100: + case 48000: + break; + default: + return -EINVAL; + } + + return 0; +} + +static size_t get_input_buffer_size(uint32_t sample_rate, audio_format_t format, int channel_count) +{ + size_t size; + size_t device_rate; + + if (check_input_parameters(sample_rate, format, channel_count) != 0) + return 0; + + /* take resampling into account and return the closest majoring + multiple of 16 frames, as audioflinger expects audio buffers to + be a multiple of 16 frames */ + size = (pcm_config_capture.period_size * sample_rate) / pcm_config_capture.rate; + size = ((size + 15) / 16) * 16; + + return size * channel_count * sizeof(short); +} + +static void add_echo_reference(struct m0_stream_out *out, + struct echo_reference_itfe *reference) +{ + pthread_mutex_lock(&out->lock); + out->echo_reference = reference; + pthread_mutex_unlock(&out->lock); +} + +static void remove_echo_reference(struct m0_stream_out *out, + struct echo_reference_itfe *reference) +{ + pthread_mutex_lock(&out->lock); + if (out->echo_reference == reference) { + /* stop writing to echo reference */ + reference->write(reference, NULL); + out->echo_reference = NULL; + } + pthread_mutex_unlock(&out->lock); +} + +static void put_echo_reference(struct m0_audio_device *adev, + struct echo_reference_itfe *reference) +{ + if (adev->echo_reference != NULL && + reference == adev->echo_reference) { + /* echo reference is taken from the low latency output stream used + * for voice use cases */ + if (adev->outputs[OUTPUT_LOW_LATENCY] != NULL && + !adev->outputs[OUTPUT_LOW_LATENCY]->standby) + remove_echo_reference(adev->outputs[OUTPUT_LOW_LATENCY], reference); + release_echo_reference(reference); + adev->echo_reference = NULL; + } +} + +static struct echo_reference_itfe *get_echo_reference(struct m0_audio_device *adev, + audio_format_t format, + uint32_t channel_count, + uint32_t sampling_rate) +{ + put_echo_reference(adev, adev->echo_reference); + /* echo reference is taken from the low latency output stream used + * for voice use cases */ + if (adev->outputs[OUTPUT_LOW_LATENCY] != NULL && + !adev->outputs[OUTPUT_LOW_LATENCY]->standby) { + struct audio_stream *stream = + &adev->outputs[OUTPUT_LOW_LATENCY]->stream.common; + uint32_t wr_channel_count = popcount(stream->get_channels(stream)); + uint32_t wr_sampling_rate = stream->get_sample_rate(stream); + + int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT, + channel_count, + sampling_rate, + AUDIO_FORMAT_PCM_16_BIT, + wr_channel_count, + wr_sampling_rate, + &adev->echo_reference); + if (status == 0) + add_echo_reference(adev->outputs[OUTPUT_LOW_LATENCY], + adev->echo_reference); + } + return adev->echo_reference; +} + +static int get_playback_delay(struct m0_stream_out *out, + size_t frames, + struct echo_reference_buffer *buffer) +{ + size_t kernel_frames; + int status; + int primary_pcm = 0; + + /* Find the first active PCM to act as primary */ + while ((primary_pcm < PCM_TOTAL) && !out->pcm[primary_pcm]) + primary_pcm++; + + status = pcm_get_htimestamp(out->pcm[primary_pcm], &kernel_frames, &buffer->time_stamp); + if (status < 0) { + buffer->time_stamp.tv_sec = 0; + buffer->time_stamp.tv_nsec = 0; + buffer->delay_ns = 0; + ALOGV("%s: pcm_get_htimestamp error," + "setting playbackTimestamp to 0", __func__); + return status; + } + + kernel_frames = pcm_get_buffer_size(out->pcm[primary_pcm]) - kernel_frames; + + /* adjust render time stamp with delay added by current driver buffer. + * Add the duration of current frame as we want the render time of the last + * sample being written. */ + buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/ + MM_FULL_POWER_SAMPLING_RATE); + + return 0; +} + +static uint32_t out_get_sample_rate(const struct audio_stream *stream) +{ + return DEFAULT_OUT_SAMPLING_RATE; +} + +static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) +{ + return 0; +} + +static size_t out_get_buffer_size_low_latency(const struct audio_stream *stream) +{ + struct m0_stream_out *out = (struct m0_stream_out *)stream; + + /* take resampling into account and return the closest majoring + multiple of 16 frames, as audioflinger expects audio buffers to + be a multiple of 16 frames. Note: we use the default rate here + from pcm_config_tones.rate. */ + size_t size = (SHORT_PERIOD_SIZE * DEFAULT_OUT_SAMPLING_RATE) / pcm_config_tones.rate; + size = ((size + 15) / 16) * 16; + return size * audio_stream_frame_size((struct audio_stream *)stream); +} + +static size_t out_get_buffer_size_deep_buffer(const struct audio_stream *stream) +{ + struct m0_stream_out *out = (struct m0_stream_out *)stream; + + /* take resampling into account and return the closest majoring + multiple of 16 frames, as audioflinger expects audio buffers to + be a multiple of 16 frames. Note: we use the default rate here + from pcm_config_mm.rate. */ + size_t size = (DEEP_BUFFER_SHORT_PERIOD_SIZE * DEFAULT_OUT_SAMPLING_RATE) / + pcm_config_mm.rate; + size = ((size + 15) / 16) * 16; + return size * audio_stream_frame_size((struct audio_stream *)stream); +} + +static audio_channel_mask_t out_get_channels(const struct audio_stream *stream) +{ + struct m0_stream_out *out = (struct m0_stream_out *)stream; + + return out->channel_mask; +} + +static audio_format_t out_get_format(const struct audio_stream *stream) +{ + return AUDIO_FORMAT_PCM_16_BIT; +} + +static int out_set_format(struct audio_stream *stream, audio_format_t format) +{ + return 0; +} + +/* must be called with hw device and output stream mutexes locked */ +static int do_output_standby(struct m0_stream_out *out) +{ + struct m0_audio_device *adev = out->dev; + int i; + bool all_outputs_in_standby = true; + + if (!out->standby) { + out->standby = 1; + + for (i = 0; i < PCM_TOTAL; i++) { + if (out->pcm[i]) { + pcm_close(out->pcm[i]); + out->pcm[i] = NULL; + } + } + + for (i = 0; i < OUTPUT_TOTAL; i++) { + if (adev->outputs[i] != NULL && !adev->outputs[i]->standby) { + all_outputs_in_standby = false; + break; + } + } + + /* force standby on low latency output stream so that it can reuse HDMI driver if + * necessary when restarted */ + if (out == adev->outputs[OUTPUT_HDMI]) { + if (adev->outputs[OUTPUT_LOW_LATENCY] != NULL && + !adev->outputs[OUTPUT_LOW_LATENCY]->standby) { + struct m0_stream_out *ll_out = adev->outputs[OUTPUT_LOW_LATENCY]; + pthread_mutex_lock(&ll_out->lock); + do_output_standby(ll_out); + pthread_mutex_unlock(&ll_out->lock); + } + } + + /* stop writing to echo reference */ + if (out->echo_reference != NULL) { + out->echo_reference->write(out->echo_reference, NULL); + out->echo_reference = NULL; + } + } + return 0; +} + +static int out_standby(struct audio_stream *stream) +{ + struct m0_stream_out *out = (struct m0_stream_out *)stream; + int status; + + pthread_mutex_lock(&out->dev->lock); + pthread_mutex_lock(&out->lock); + status = do_output_standby(out); + pthread_mutex_unlock(&out->lock); + pthread_mutex_unlock(&out->dev->lock); + return status; +} + +static int out_dump(const struct audio_stream *stream, int fd) +{ + return 0; +} + +static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) +{ + struct m0_stream_out *out = (struct m0_stream_out *)stream; + struct m0_audio_device *adev = out->dev; + struct m0_stream_in *in; + struct str_parms *parms; + char *str; + char value[32]; + int ret, val = 0; + bool force_input_standby = false; + + parms = str_parms_create_str(kvpairs); + + ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); + if (ret >= 0) { + val = atoi(value); + pthread_mutex_lock(&adev->lock); + pthread_mutex_lock(&out->lock); + if (((adev->out_device) != val) && (val != 0)) { + /* this is needed only when changing device on low latency output + * as other output streams are not used for voice use cases nor + * handle duplication to HDMI or SPDIF */ + if (out == adev->outputs[OUTPUT_LOW_LATENCY] && !out->standby) { + /* a change in output device may change the microphone selection */ + if (adev->active_input && + adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) { + force_input_standby = true; + } + /* force standby if moving to/from HDMI/SPDIF or if the output + * device changes when in HDMI/SPDIF mode */ + /* FIXME also force standby when in call as some audio path switches do not work + * while in call and an output stream is active (e.g BT SCO => earpiece) */ + + /* FIXME workaround for audio being dropped when switching path without forcing standby + * (several hundred ms of audio can be lost: e.g beginning of a ringtone. We must understand + * the root cause in audio HAL, driver or ABE. + if (((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) ^ + (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) || + ((val & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ^ + (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) || + (adev->out_device & (AUDIO_DEVICE_OUT_AUX_DIGITAL | + AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET))) + */ + if (((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) ^ + (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) || + ((val & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ^ + (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) || + (adev->out_device & (AUDIO_DEVICE_OUT_AUX_DIGITAL | + AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) || + ((val & AUDIO_DEVICE_OUT_SPEAKER) ^ + (adev->out_device & AUDIO_DEVICE_OUT_SPEAKER)) || + (adev->mode == AUDIO_MODE_IN_CALL)) + do_output_standby(out); + } + if (out != adev->outputs[OUTPUT_HDMI]) { + adev->out_device = val; + select_output_device(adev); + } + } + pthread_mutex_unlock(&out->lock); + if (force_input_standby) { + in = adev->active_input; + pthread_mutex_lock(&in->lock); + do_input_standby(in); + pthread_mutex_unlock(&in->lock); + } + pthread_mutex_unlock(&adev->lock); + } + + str_parms_destroy(parms); + return ret; +} + +static char * out_get_parameters(const struct audio_stream *stream, const char *keys) +{ + struct m0_stream_out *out = (struct m0_stream_out *)stream; + + struct str_parms *query = str_parms_create_str(keys); + char *str; + char value[256]; + struct str_parms *reply = str_parms_create(); + size_t i, j; + int ret; + bool first = true; + + ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value)); + if (ret >= 0) { + value[0] = '\0'; + i = 0; + while (out->sup_channel_masks[i] != 0) { + for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) { + if (out_channels_name_to_enum_table[j].value == out->sup_channel_masks[i]) { + if (!first) { + strcat(value, "|"); + } + strcat(value, out_channels_name_to_enum_table[j].name); + first = false; + break; + } + } + i++; + } + str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value); + str = strdup(str_parms_to_str(reply)); + } else { + str = strdup(keys); + } + str_parms_destroy(query); + str_parms_destroy(reply); + return str; +} + +static uint32_t out_get_latency_low_latency(const struct audio_stream_out *stream) +{ + struct m0_stream_out *out = (struct m0_stream_out *)stream; + + /* Note: we use the default rate here from pcm_config_mm.rate */ + return (SHORT_PERIOD_SIZE * PLAYBACK_SHORT_PERIOD_COUNT * 1000) / pcm_config_tones.rate; +} + +static uint32_t out_get_latency_deep_buffer(const struct audio_stream_out *stream) +{ + struct m0_stream_out *out = (struct m0_stream_out *)stream; + + /* Note: we use the default rate here from pcm_config_mm.rate */ + return (DEEP_BUFFER_LONG_PERIOD_SIZE * PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT * 1000) / + pcm_config_mm.rate; +} + +static int out_set_volume(struct audio_stream_out *stream, float left, + float right) +{ + return -ENOSYS; +} + +static ssize_t out_write_low_latency(struct audio_stream_out *stream, const void* buffer, + size_t bytes) +{ + int ret; + struct m0_stream_out *out = (struct m0_stream_out *)stream; + struct m0_audio_device *adev = out->dev; + size_t frame_size = audio_stream_frame_size(&out->stream.common); + size_t in_frames = bytes / frame_size; + size_t out_frames = in_frames; + bool force_input_standby = false; + struct m0_stream_in *in; + int i; + + /* acquiring hw device mutex systematically is useful if a low priority thread is waiting + * on the output stream mutex - e.g. executing select_mode() while holding the hw device + * mutex + */ + pthread_mutex_lock(&adev->lock); + pthread_mutex_lock(&out->lock); + if (out->standby) { + ret = start_output_stream_low_latency(out); + if (ret != 0) { + pthread_mutex_unlock(&adev->lock); + goto exit; + } + out->standby = 0; + /* a change in output device may change the microphone selection */ + if (adev->active_input && + adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) + force_input_standby = true; + } + pthread_mutex_unlock(&adev->lock); + + for (i = 0; i < PCM_TOTAL; i++) { + /* only use resampler if required */ + if (out->pcm[i] && (out->config[i].rate != DEFAULT_OUT_SAMPLING_RATE)) { + out_frames = out->buffer_frames; + out->resampler->resample_from_input(out->resampler, + (int16_t *)buffer, + &in_frames, + (int16_t *)out->buffer, + &out_frames); + break; + } + } + + if (out->echo_reference != NULL) { + struct echo_reference_buffer b; + b.raw = (void *)buffer; + b.frame_count = in_frames; + + get_playback_delay(out, out_frames, &b); + out->echo_reference->write(out->echo_reference, &b); + } + + /* Write to all active PCMs */ + for (i = 0; i < PCM_TOTAL; i++) { + if (out->pcm[i]) { + if (out->config[i].rate == DEFAULT_OUT_SAMPLING_RATE) { + /* PCM uses native sample rate */ + ret = PCM_WRITE(out->pcm[i], (void *)buffer, bytes); + } else { + /* PCM needs resampler */ + ret = PCM_WRITE(out->pcm[i], (void *)out->buffer, out_frames * frame_size); + } + if (ret) + break; + } + } + +exit: + pthread_mutex_unlock(&out->lock); + + if (ret != 0) { + usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / + out_get_sample_rate(&stream->common)); + } + + if (force_input_standby) { + pthread_mutex_lock(&adev->lock); + if (adev->active_input) { + in = adev->active_input; + pthread_mutex_lock(&in->lock); + do_input_standby(in); + pthread_mutex_unlock(&in->lock); + } + pthread_mutex_unlock(&adev->lock); + } + + return bytes; +} + +static ssize_t out_write_deep_buffer(struct audio_stream_out *stream, const void* buffer, + size_t bytes) +{ + int ret; + struct m0_stream_out *out = (struct m0_stream_out *)stream; + struct m0_audio_device *adev = out->dev; + size_t frame_size = audio_stream_frame_size(&out->stream.common); + size_t in_frames = bytes / frame_size; + size_t out_frames; + bool use_long_periods; + int kernel_frames; + void *buf; + + /* acquiring hw device mutex systematically is useful if a low priority thread is waiting + * on the output stream mutex - e.g. executing select_mode() while holding the hw device + * mutex + */ + pthread_mutex_lock(&adev->lock); + pthread_mutex_lock(&out->lock); + if (out->standby) { + ret = start_output_stream_deep_buffer(out); + if (ret != 0) { + pthread_mutex_unlock(&adev->lock); + goto exit; + } + out->standby = 0; + } + use_long_periods = adev->screen_off && !adev->active_input; + pthread_mutex_unlock(&adev->lock); + + if (use_long_periods != out->use_long_periods) { + size_t period_size; + size_t period_count; + + if (use_long_periods) { + period_size = DEEP_BUFFER_LONG_PERIOD_SIZE; + period_count = PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT; + } else { + period_size = DEEP_BUFFER_SHORT_PERIOD_SIZE; + period_count = PLAYBACK_DEEP_BUFFER_SHORT_PERIOD_COUNT; + } + out->write_threshold = period_size * period_count; + pcm_set_avail_min(out->pcm[PCM_NORMAL], period_size); + out->use_long_periods = use_long_periods; + } + + /* only use resampler if required */ + if (out->config[PCM_NORMAL].rate != DEFAULT_OUT_SAMPLING_RATE) { + out_frames = out->buffer_frames; + out->resampler->resample_from_input(out->resampler, + (int16_t *)buffer, + &in_frames, + (int16_t *)out->buffer, + &out_frames); + buf = (void *)out->buffer; + } else { + out_frames = in_frames; + buf = (void *)buffer; + } + + /* do not allow more than out->write_threshold frames in kernel pcm driver buffer */ + do { + struct timespec time_stamp; + + if (pcm_get_htimestamp(out->pcm[PCM_NORMAL], + (unsigned int *)&kernel_frames, &time_stamp) < 0) + break; + kernel_frames = pcm_get_buffer_size(out->pcm[PCM_NORMAL]) - kernel_frames; + + if (kernel_frames > out->write_threshold) { + unsigned long time = (unsigned long) + (((int64_t)(kernel_frames - out->write_threshold) * 1000000) / + MM_FULL_POWER_SAMPLING_RATE); + if (time < MIN_WRITE_SLEEP_US) + time = MIN_WRITE_SLEEP_US; + usleep(time); + } + } while (kernel_frames > out->write_threshold); + + ret = pcm_mmap_write(out->pcm[PCM_NORMAL], buf, out_frames * frame_size); + +exit: + pthread_mutex_unlock(&out->lock); + + if (ret != 0) { + usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / + out_get_sample_rate(&stream->common)); + } + + return bytes; +} + +static int out_get_render_position(const struct audio_stream_out *stream, + uint32_t *dsp_frames) +{ + return -EINVAL; +} + +static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) +{ + return 0; +} + +static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) +{ + return 0; +} + +/** audio_stream_in implementation **/ + +/* must be called with hw device and input stream mutexes locked */ +static int start_input_stream(struct m0_stream_in *in) +{ + int ret = 0; + struct m0_audio_device *adev = in->dev; + + adev->active_input = in; + + if (adev->mode != AUDIO_MODE_IN_CALL) { + adev->in_device = in->device; + select_input_device(adev); + } + + if (in->aux_channels_changed) + { + in->aux_channels_changed = false; + in->config.channels = popcount(in->main_channels | in->aux_channels); + + if (in->resampler) { + /* release and recreate the resampler with the new number of channel of the input */ + release_resampler(in->resampler); + in->resampler = NULL; + ret = create_resampler(in->config.rate, + in->requested_rate, + in->config.channels, + RESAMPLER_QUALITY_DEFAULT, + &in->buf_provider, + &in->resampler); + } + ALOGV("%s: New channel configuration, " + "main_channels = [%04x], aux_channels = [%04x], config.channels = %d", + __func__, in->main_channels, in->aux_channels, in->config.channels); + } + + if (in->need_echo_reference && in->echo_reference == NULL) + in->echo_reference = get_echo_reference(adev, + AUDIO_FORMAT_PCM_16_BIT, + popcount(in->main_channels), + in->requested_rate); + + /* this assumes routing is done previously */ + in->pcm = pcm_open(CARD_DEFAULT, PORT_CAPTURE, PCM_IN, &in->config); + if (!pcm_is_ready(in->pcm)) { + ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm)); + pcm_close(in->pcm); + adev->active_input = NULL; + return -ENOMEM; + } + + /* force read and proc buf reallocation case of frame size or channel count change */ + in->read_buf_frames = 0; + in->read_buf_size = 0; + in->proc_buf_frames = 0; + in->proc_buf_size = 0; + /* if no supported sample rate is available, use the resampler */ + if (in->resampler) { + in->resampler->reset(in->resampler); + } + return 0; +} + +static uint32_t in_get_sample_rate(const struct audio_stream *stream) +{ + struct m0_stream_in *in = (struct m0_stream_in *)stream; + + return in->requested_rate; +} + +static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) +{ + return 0; +} + +static size_t in_get_buffer_size(const struct audio_stream *stream) +{ + struct m0_stream_in *in = (struct m0_stream_in *)stream; + + return get_input_buffer_size(in->requested_rate, + AUDIO_FORMAT_PCM_16_BIT, + popcount(in->main_channels)); +} + +static audio_channel_mask_t in_get_channels(const struct audio_stream *stream) +{ + struct m0_stream_in *in = (struct m0_stream_in *)stream; + + return in->main_channels; +} + +static audio_format_t in_get_format(const struct audio_stream *stream) +{ + return AUDIO_FORMAT_PCM_16_BIT; +} + +static int in_set_format(struct audio_stream *stream, audio_format_t format) +{ + return 0; +} + +/* must be called with hw device and input stream mutexes locked */ +static int do_input_standby(struct m0_stream_in *in) +{ + struct m0_audio_device *adev = in->dev; + + if (!in->standby) { + pcm_close(in->pcm); + in->pcm = NULL; + + adev->active_input = 0; + if (adev->mode != AUDIO_MODE_IN_CALL) { + adev->in_device = AUDIO_DEVICE_NONE; + select_input_device(adev); + } + + if (in->echo_reference != NULL) { + /* stop reading from echo reference */ + in->echo_reference->read(in->echo_reference, NULL); + put_echo_reference(adev, in->echo_reference); + in->echo_reference = NULL; + } + + in->standby = 1; + } + return 0; +} + +static int in_standby(struct audio_stream *stream) +{ + struct m0_stream_in *in = (struct m0_stream_in *)stream; + int status; + + pthread_mutex_lock(&in->dev->lock); + pthread_mutex_lock(&in->lock); + status = do_input_standby(in); + pthread_mutex_unlock(&in->lock); + pthread_mutex_unlock(&in->dev->lock); + return status; +} + +static int in_dump(const struct audio_stream *stream, int fd) +{ + return 0; +} + +static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) +{ + struct m0_stream_in *in = (struct m0_stream_in *)stream; + struct m0_audio_device *adev = in->dev; + struct str_parms *parms; + char *str; + char value[32]; + int ret, val = 0; + bool do_standby = false; + + parms = str_parms_create_str(kvpairs); + + ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value)); + + pthread_mutex_lock(&adev->lock); + pthread_mutex_lock(&in->lock); + if (ret >= 0) { + val = atoi(value); + /* no audio source uses val == 0 */ + if ((in->source != val) && (val != 0)) { + in->source = val; + do_standby = true; + } + } + + ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); + if (ret >= 0) { + val = atoi(value) & ~AUDIO_DEVICE_BIT_IN; + if ((in->device != val) && (val != 0)) { + in->device = val; + do_standby = true; + /* make sure new device selection is incompatible with multi-mic pre processing + * configuration */ + in_update_aux_channels(in, NULL); + } + } + + if (do_standby) + do_input_standby(in); + pthread_mutex_unlock(&in->lock); + pthread_mutex_unlock(&adev->lock); + + str_parms_destroy(parms); + return ret; +} + +static char * in_get_parameters(const struct audio_stream *stream, + const char *keys) +{ + return strdup(""); +} + +static int in_set_gain(struct audio_stream_in *stream, float gain) +{ + return 0; +} + +static void get_capture_delay(struct m0_stream_in *in, + size_t frames, + struct echo_reference_buffer *buffer) +{ + + /* read frames available in kernel driver buffer */ + size_t kernel_frames; + struct timespec tstamp; + long buf_delay; + long rsmp_delay; + long kernel_delay; + long delay_ns; + + if (pcm_get_htimestamp(in->pcm, &kernel_frames, &tstamp) < 0) { + buffer->time_stamp.tv_sec = 0; + buffer->time_stamp.tv_nsec = 0; + buffer->delay_ns = 0; + ALOGW("%s: pcm_htimestamp error", __func__); + return; + } + + /* read frames available in audio HAL input buffer + * add number of frames being read as we want the capture time of first sample + * in current buffer */ + /* frames in in->buffer are at driver sampling rate while frames in in->proc_buf are + * at requested sampling rate */ + buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate + + ((int64_t)(in->proc_buf_frames) * 1000000000) / + in->requested_rate); + + /* add delay introduced by resampler */ + rsmp_delay = 0; + if (in->resampler) { + rsmp_delay = in->resampler->delay_ns(in->resampler); + } + + kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate); + + delay_ns = kernel_delay + buf_delay + rsmp_delay; + + buffer->time_stamp = tstamp; + buffer->delay_ns = delay_ns; + ALOGV("%s: time_stamp = [%ld].[%ld], delay_ns: [%d]," + " kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], kernel_frames:[%d], " + "in->read_buf_frames:[%d], in->proc_buf_frames:[%d], frames:[%d]", + __func__, buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns, + kernel_delay, buf_delay, rsmp_delay, kernel_frames, + in->read_buf_frames, in->proc_buf_frames, frames); + +} + +static int32_t update_echo_reference(struct m0_stream_in *in, size_t frames) +{ + struct echo_reference_buffer b; + b.delay_ns = 0; + + ALOGV("%s: frames = [%d], in->ref_frames_in = [%d], " + "b.frame_count = [%d]", + __func__, frames, in->ref_buf_frames, frames - in->ref_buf_frames); + if (in->ref_buf_frames < frames) { + if (in->ref_buf_size < frames) { + in->ref_buf_size = frames; + in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(in->pcm, frames)); + ALOG_ASSERT((in->ref_buf != NULL), + "%s failed to reallocate ref_buf", __func__); + ALOGV("%s: ref_buf %p extended to %d bytes", + __func__, in->ref_buf, pcm_frames_to_bytes(in->pcm, frames)); + } + b.frame_count = frames - in->ref_buf_frames; + b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels); + + get_capture_delay(in, frames, &b); + + if (in->echo_reference->read(in->echo_reference, &b) == 0) + { + in->ref_buf_frames += b.frame_count; + ALOGD("%s: in->ref_buf_frames:[%d], " + "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]", + __func__, in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count); + } + } else + ALOGW("%s: NOT enough frames to read ref buffer", __func__); + return b.delay_ns; +} + +static int set_preprocessor_param(effect_handle_t handle, + effect_param_t *param) +{ + uint32_t size = sizeof(int); + uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + + param->vsize; + + int status = (*handle)->command(handle, + EFFECT_CMD_SET_PARAM, + sizeof (effect_param_t) + psize, + param, + &size, + ¶m->status); + if (status == 0) + status = param->status; + + return status; +} + +static int set_preprocessor_echo_delay(effect_handle_t handle, + int32_t delay_us) +{ + uint32_t buf[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; + effect_param_t *param = (effect_param_t *)buf; + + param->psize = sizeof(uint32_t); + param->vsize = sizeof(uint32_t); + *(uint32_t *)param->data = AEC_PARAM_ECHO_DELAY; + *((int32_t *)param->data + 1) = delay_us; + + return set_preprocessor_param(handle, param); +} + +static void push_echo_reference(struct m0_stream_in *in, size_t frames) +{ + /* read frames from echo reference buffer and update echo delay + * in->ref_buf_frames is updated with frames available in in->ref_buf */ + int32_t delay_us = update_echo_reference(in, frames)/1000; + int i; + audio_buffer_t buf; + + if (in->ref_buf_frames < frames) + frames = in->ref_buf_frames; + + buf.frameCount = frames; + buf.raw = in->ref_buf; + + for (i = 0; i < in->num_preprocessors; i++) { + if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL) + continue; + + (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe, + &buf, + NULL); + set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us); + } + + in->ref_buf_frames -= buf.frameCount; + if (in->ref_buf_frames) { + memcpy(in->ref_buf, + in->ref_buf + buf.frameCount * in->config.channels, + in->ref_buf_frames * in->config.channels * sizeof(int16_t)); + } +} + +static int get_next_buffer(struct resampler_buffer_provider *buffer_provider, + struct resampler_buffer* buffer) +{ + struct m0_stream_in *in; + + if (buffer_provider == NULL || buffer == NULL) + return -EINVAL; + + in = (struct m0_stream_in *)((char *)buffer_provider - + offsetof(struct m0_stream_in, buf_provider)); + + if (in->pcm == NULL) { + buffer->raw = NULL; + buffer->frame_count = 0; + in->read_status = -ENODEV; + return -ENODEV; + } + + if (in->read_buf_frames == 0) { + size_t size_in_bytes = pcm_frames_to_bytes(in->pcm, in->config.period_size); + if (in->read_buf_size < in->config.period_size) { + in->read_buf_size = in->config.period_size; + in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes); + ALOG_ASSERT((in->read_buf != NULL), + "%s failed to reallocate read_buf", __func__); + ALOGV("%s: read_buf %p extended to %d bytes", + __func__, in->read_buf, size_in_bytes); + } + + in->read_status = pcm_read(in->pcm, (void*)in->read_buf, size_in_bytes); + + if (in->read_status != 0) { + ALOGE("%s: pcm_read error %d", __func__, in->read_status); + buffer->raw = NULL; + buffer->frame_count = 0; + return in->read_status; + } + in->read_buf_frames = in->config.period_size; + } + + buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ? + in->read_buf_frames : buffer->frame_count; + buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) * + in->config.channels; + + return in->read_status; + +} + +static void release_buffer(struct resampler_buffer_provider *buffer_provider, + struct resampler_buffer* buffer) +{ + struct m0_stream_in *in; + + if (buffer_provider == NULL || buffer == NULL) + return; + + in = (struct m0_stream_in *)((char *)buffer_provider - + offsetof(struct m0_stream_in, buf_provider)); + + in->read_buf_frames -= buffer->frame_count; +} + +/* read_frames() reads frames from kernel driver, down samples to capture rate + * if necessary and output the number of frames requested to the buffer specified */ +static ssize_t read_frames(struct m0_stream_in *in, void *buffer, ssize_t frames) +{ + ssize_t frames_wr = 0; + + while (frames_wr < frames) { + size_t frames_rd = frames - frames_wr; + if (in->resampler != NULL) { + in->resampler->resample_from_provider(in->resampler, + (int16_t *)((char *)buffer + + pcm_frames_to_bytes(in->pcm ,frames_wr)), + &frames_rd); + + } else { + struct resampler_buffer buf = { + { raw : NULL, }, + frame_count : frames_rd, + }; + get_next_buffer(&in->buf_provider, &buf); + if (buf.raw != NULL) { + memcpy((char *)buffer + + pcm_frames_to_bytes(in->pcm, frames_wr), + buf.raw, + pcm_frames_to_bytes(in->pcm, buf.frame_count)); + frames_rd = buf.frame_count; + } + release_buffer(&in->buf_provider, &buf); + } + /* in->read_status is updated by getNextBuffer() also called by + * in->resampler->resample_from_provider() */ + if (in->read_status != 0) + return in->read_status; + + frames_wr += frames_rd; + } + return frames_wr; +} + +/* process_frames() reads frames from kernel driver (via read_frames()), + * calls the active audio pre processings and output the number of frames requested + * to the buffer specified */ +static ssize_t process_frames(struct m0_stream_in *in, void* buffer, ssize_t frames) +{ + ssize_t frames_wr = 0; + audio_buffer_t in_buf; + audio_buffer_t out_buf; + int i; + bool has_aux_channels = (~in->main_channels & in->aux_channels); + void *proc_buf_out; + + if (has_aux_channels) + proc_buf_out = in->proc_buf_out; + else + proc_buf_out = buffer; + + /* since all the processing below is done in frames and using the config.channels + * as the number of channels, no changes is required in case aux_channels are present */ + while (frames_wr < frames) { + /* first reload enough frames at the end of process input buffer */ + if (in->proc_buf_frames < (size_t)frames) { + ssize_t frames_rd; + + if (in->proc_buf_size < (size_t)frames) { + size_t size_in_bytes = pcm_frames_to_bytes(in->pcm, frames); + + in->proc_buf_size = (size_t)frames; + in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes); + ALOG_ASSERT((in->proc_buf_in != NULL), + "%s failed to reallocate proc_buf_in", __func__); + if (has_aux_channels) { + in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes); + ALOG_ASSERT((in->proc_buf_out != NULL), + "%s failed to reallocate proc_buf_out", __func__); + proc_buf_out = in->proc_buf_out; + } + ALOGV("process_frames(): proc_buf_in %p extended to %d bytes", + in->proc_buf_in, size_in_bytes); + } + frames_rd = read_frames(in, + in->proc_buf_in + + in->proc_buf_frames * in->config.channels, + frames - in->proc_buf_frames); + if (frames_rd < 0) { + frames_wr = frames_rd; + break; + } + in->proc_buf_frames += frames_rd; + } + + if (in->echo_reference != NULL) + push_echo_reference(in, in->proc_buf_frames); + + /* in_buf.frameCount and out_buf.frameCount indicate respectively + * the maximum number of frames to be consumed and produced by process() */ + in_buf.frameCount = in->proc_buf_frames; + in_buf.s16 = in->proc_buf_in; + out_buf.frameCount = frames - frames_wr; + out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels; + + /* FIXME: this works because of current pre processing library implementation that + * does the actual process only when the last enabled effect process is called. + * The generic solution is to have an output buffer for each effect and pass it as + * input to the next. + */ + for (i = 0; i < in->num_preprocessors; i++) { + (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe, + &in_buf, + &out_buf); + } + + /* process() has updated the number of frames consumed and produced in + * in_buf.frameCount and out_buf.frameCount respectively + * move remaining frames to the beginning of in->proc_buf_in */ + in->proc_buf_frames -= in_buf.frameCount; + + if (in->proc_buf_frames) { + memcpy(in->proc_buf_in, + in->proc_buf_in + in_buf.frameCount * in->config.channels, + in->proc_buf_frames * in->config.channels * sizeof(int16_t)); + } + + /* if not enough frames were passed to process(), read more and retry. */ + if (out_buf.frameCount == 0) { + ALOGW("No frames produced by preproc"); + continue; + } + + if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) { + frames_wr += out_buf.frameCount; + } else { + /* The effect does not comply to the API. In theory, we should never end up here! */ + ALOGE("%s: preprocessing produced too many frames: %d + %d > %d !", __func__, + (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames); + frames_wr = frames; + } + } + + /* Remove aux_channels that have been added on top of main_channels + * Assumption is made that the channels are interleaved and that the main + * channels are first. */ + if (has_aux_channels) + { + size_t src_channels = in->config.channels; + size_t dst_channels = popcount(in->main_channels); + int16_t* src_buffer = (int16_t *)proc_buf_out; + int16_t* dst_buffer = (int16_t *)buffer; + + if (dst_channels == 1) { + for (i = frames_wr; i > 0; i--) + { + *dst_buffer++ = *src_buffer; + src_buffer += src_channels; + } + } else { + for (i = frames_wr; i > 0; i--) + { + memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t)); + dst_buffer += dst_channels; + src_buffer += src_channels; + } + } + } + + return frames_wr; +} + +static ssize_t in_read(struct audio_stream_in *stream, void* buffer, + size_t bytes) +{ + int ret = 0; + struct m0_stream_in *in = (struct m0_stream_in *)stream; + struct m0_audio_device *adev = in->dev; + size_t frames_rq = bytes / audio_stream_frame_size(&stream->common); + + /* acquiring hw device mutex systematically is useful if a low priority thread is waiting + * on the input stream mutex - e.g. executing select_mode() while holding the hw device + * mutex + */ + pthread_mutex_lock(&adev->lock); + pthread_mutex_lock(&in->lock); + if (in->standby) { + ret = start_input_stream(in); + if (ret == 0) + in->standby = 0; + } + pthread_mutex_unlock(&adev->lock); + + if (ret < 0) + goto exit; + + if (in->num_preprocessors != 0) + ret = process_frames(in, buffer, frames_rq); + else if (in->resampler != NULL) + ret = read_frames(in, buffer, frames_rq); + else + ret = pcm_read(in->pcm, buffer, bytes); + + if (ret > 0) + ret = 0; + + if (ret == 0 && adev->mic_mute) + memset(buffer, 0, bytes); + +exit: + if (ret < 0) + usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / + in_get_sample_rate(&stream->common)); + + pthread_mutex_unlock(&in->lock); + return bytes; +} + +static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) +{ + return 0; +} + +#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \ + do { \ + if (fct_status != 0) \ + status = fct_status; \ + else if (cmd_status != 0) \ + status = cmd_status; \ + } while(0) + +static int in_configure_reverse(struct m0_stream_in *in) +{ + int32_t cmd_status; + uint32_t size = sizeof(int); + effect_config_t config; + int32_t status = 0; + int32_t fct_status = 0; + int i; + + if (in->num_preprocessors > 0) { + config.inputCfg.channels = in->main_channels; + config.outputCfg.channels = in->main_channels; + config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; + config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; + config.inputCfg.samplingRate = in->requested_rate; + config.outputCfg.samplingRate = in->requested_rate; + config.inputCfg.mask = + ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT ); + config.outputCfg.mask = + ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT ); + + for (i = 0; i < in->num_preprocessors; i++) + { + if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL) + continue; + fct_status = (*(in->preprocessors[i].effect_itfe))->command( + in->preprocessors[i].effect_itfe, + EFFECT_CMD_SET_CONFIG_REVERSE, + sizeof(effect_config_t), + &config, + &size, + &cmd_status); + GET_COMMAND_STATUS(status, fct_status, cmd_status); + } + } + return status; +} + +#define MAX_NUM_CHANNEL_CONFIGS 10 + +static void in_read_audio_effect_channel_configs(struct m0_stream_in *in, + struct effect_info_s *effect_info) +{ + /* size and format of the cmd are defined in hardware/audio_effect.h */ + effect_handle_t effect = effect_info->effect_itfe; + uint32_t cmd_size = 2 * sizeof(uint32_t); + uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS }; + /* reply = status + number of configs (n) + n x channel_config_t */ + uint32_t reply_size = + 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t)); + int32_t reply[reply_size]; + int32_t cmd_status; + + ALOG_ASSERT((effect_info->num_channel_configs == 0), + "in_read_audio_effect_channel_configs() num_channel_configs not cleared"); + ALOG_ASSERT((effect_info->channel_configs == NULL), + "in_read_audio_effect_channel_configs() channel_configs not cleared"); + + /* if this command is not supported, then the effect is supposed to return -EINVAL. + * This error will be interpreted as if the effect supports the main_channels but does not + * support any aux_channels */ + cmd_status = (*effect)->command(effect, + EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS, + cmd_size, + (void*)&cmd, + &reply_size, + (void*)&reply); + + if (cmd_status != 0) { + ALOGI("%s: fx->command returned %d", __func__, cmd_status); + return; + } + + if (reply[0] != 0) { + ALOGW("%s: " + "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d", + __func__, reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS); + return; + } + + /* the feature is not supported */ + ALOGI("in_read_audio_effect_channel_configs()(): " + "Feature supported and adding %d channel configs to the list", reply[1]); + effect_info->num_channel_configs = reply[1]; + effect_info->channel_configs = + (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */ + memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]); +} + + +static uint32_t in_get_aux_channels(struct m0_stream_in *in) +{ + int i; + channel_config_t new_chcfg = {0, 0}; + + if (in->num_preprocessors == 0) + return 0; + + /* do not enable dual mic configurations when capturing from other microphones than + * main or sub */ + if (!(in->device & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC))) + return 0; + + /* retain most complex aux channels configuration compatible with requested main channels and + * supported by audio driver and all pre processors */ + for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) { + channel_config_t *cur_chcfg = &in_aux_cnl_configs[i]; + if (cur_chcfg->main_channels == in->main_channels) { + size_t match_cnt; + size_t idx_preproc; + for (idx_preproc = 0, match_cnt = 0; + /* no need to continue if at least one preprocessor doesn't match */ + idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc; + idx_preproc++) { + struct effect_info_s *effect_info = &in->preprocessors[idx_preproc]; + size_t idx_chcfg; + + for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) { + if (memcmp(effect_info->channel_configs + idx_chcfg, + cur_chcfg, + sizeof(channel_config_t)) == 0) { + match_cnt++; + break; + } + } + } + /* if all preprocessors match, we have a candidate */ + if (match_cnt == (size_t)in->num_preprocessors) { + /* retain most complex aux channels configuration */ + if (popcount(cur_chcfg->aux_channels) > popcount(new_chcfg.aux_channels)) { + new_chcfg = *cur_chcfg; + } + } + } + } + + ALOGI("in_get_aux_channels(): return %04x", new_chcfg.aux_channels); + + return new_chcfg.aux_channels; +} + +static int in_configure_effect_channels(effect_handle_t effect, + channel_config_t *channel_config) +{ + int status = 0; + int fct_status; + int32_t cmd_status; + uint32_t reply_size; + effect_config_t config; + uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1]; + + ALOGI("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]", + channel_config->main_channels, + channel_config->aux_channels); + + config.inputCfg.mask = EFFECT_CONFIG_CHANNELS; + config.outputCfg.mask = EFFECT_CONFIG_CHANNELS; + reply_size = sizeof(effect_config_t); + fct_status = (*effect)->command(effect, + EFFECT_CMD_GET_CONFIG, + 0, + NULL, + &reply_size, + &config); + if (fct_status != 0) { + ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed"); + return fct_status; + } + + config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels; + config.outputCfg.channels = config.inputCfg.channels; + reply_size = sizeof(uint32_t); + fct_status = (*effect)->command(effect, + EFFECT_CMD_SET_CONFIG, + sizeof(effect_config_t), + &config, + &reply_size, + &cmd_status); + GET_COMMAND_STATUS(status, fct_status, cmd_status); + + cmd[0] = EFFECT_FEATURE_AUX_CHANNELS; + memcpy(cmd + 1, channel_config, sizeof(channel_config_t)); + reply_size = sizeof(uint32_t); + fct_status = (*effect)->command(effect, + EFFECT_CMD_SET_FEATURE_CONFIG, + sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t), + cmd, + &reply_size, + &cmd_status); + GET_COMMAND_STATUS(status, fct_status, cmd_status); + + /* some implementations need to be re-enabled after a config change */ + reply_size = sizeof(uint32_t); + fct_status = (*effect)->command(effect, + EFFECT_CMD_ENABLE, + 0, + NULL, + &reply_size, + &cmd_status); + GET_COMMAND_STATUS(status, fct_status, cmd_status); + + return status; +} + +static int in_reconfigure_channels(struct m0_stream_in *in, + effect_handle_t effect, + channel_config_t *channel_config, + bool config_changed) { + + int status = 0; + + ALOGI("%s: config_changed %d effect %p", + __func__, config_changed, effect); + + /* if config changed, reconfigure all previously added effects */ + if (config_changed) { + int i; + for (i = 0; i < in->num_preprocessors; i++) + { + int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe, + channel_config); + if (cur_status != 0) { + ALOGI("%s: error %d configuring effect " + "%d with channels: [%04x][%04x]", + __func__, + cur_status, + i, + channel_config->main_channels, + channel_config->aux_channels); + status = cur_status; + } + } + } else if (effect != NULL && channel_config->aux_channels) { + /* if aux channels config did not change but aux channels are present, + * we still need to configure the effect being added */ + status = in_configure_effect_channels(effect, channel_config); + } + return status; +} + +static void in_update_aux_channels(struct m0_stream_in *in, + effect_handle_t effect) +{ + uint32_t aux_channels; + channel_config_t channel_config; + int status; + + aux_channels = in_get_aux_channels(in); + + channel_config.main_channels = in->main_channels; + channel_config.aux_channels = aux_channels; + status = in_reconfigure_channels(in, + effect, + &channel_config, + (aux_channels != in->aux_channels)); + + if (status != 0) { + ALOGI("%s: in_reconfigure_channels error %d", __func__, status); + /* resetting aux channels configuration */ + aux_channels = 0; + channel_config.aux_channels = 0; + in_reconfigure_channels(in, effect, &channel_config, true); + } + if (in->aux_channels != aux_channels) { + in->aux_channels_changed = true; + in->aux_channels = aux_channels; + do_input_standby(in); + } +} + +static int in_add_audio_effect(const struct audio_stream *stream, + effect_handle_t effect) +{ + struct m0_stream_in *in = (struct m0_stream_in *)stream; + int status; + effect_descriptor_t desc; + + pthread_mutex_lock(&in->dev->lock); + pthread_mutex_lock(&in->lock); + if (in->num_preprocessors >= MAX_PREPROCESSORS) { + status = -ENOSYS; + goto exit; + } + + status = (*effect)->get_descriptor(effect, &desc); + if (status != 0) + goto exit; + + in->preprocessors[in->num_preprocessors].effect_itfe = effect; + /* add the supported channel of the effect in the channel_configs */ + in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]); + + in->num_preprocessors++; + + /* check compatibility between main channel supported and possible auxiliary channels */ + in_update_aux_channels(in, effect); + + ALOGV("%s: effect type: %08x", __func__, desc.type.timeLow); + + if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) { + in->need_echo_reference = true; + do_input_standby(in); + in_configure_reverse(in); + } + +exit: + + ALOGW_IF(status != 0, "%s: error %d", __func__, status); + pthread_mutex_unlock(&in->lock); + pthread_mutex_unlock(&in->dev->lock); + return status; +} + +static int in_remove_audio_effect(const struct audio_stream *stream, + effect_handle_t effect) +{ + struct m0_stream_in *in = (struct m0_stream_in *)stream; + int i; + int status = -EINVAL; + effect_descriptor_t desc; + + pthread_mutex_lock(&in->dev->lock); + pthread_mutex_lock(&in->lock); + if (in->num_preprocessors <= 0) { + status = -ENOSYS; + goto exit; + } + + for (i = 0; i < in->num_preprocessors; i++) { + if (status == 0) { /* status == 0 means an effect was removed from a previous slot */ + in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe; + in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs; + in->preprocessors[i - 1].num_channel_configs = in->preprocessors[i].num_channel_configs; + ALOGI("in_remove_audio_effect moving fx from %d to %d", i, i - 1); + continue; + } + if (in->preprocessors[i].effect_itfe == effect) { + ALOGI("in_remove_audio_effect found fx at index %d", i); + free(in->preprocessors[i].channel_configs); + status = 0; + } + } + + if (status != 0) + goto exit; + + in->num_preprocessors--; + /* if we remove one effect, at least the last preproc should be reset */ + in->preprocessors[in->num_preprocessors].num_channel_configs = 0; + in->preprocessors[in->num_preprocessors].effect_itfe = NULL; + in->preprocessors[in->num_preprocessors].channel_configs = NULL; + + + /* check compatibility between main channel supported and possible auxiliary channels */ + in_update_aux_channels(in, NULL); + + status = (*effect)->get_descriptor(effect, &desc); + if (status != 0) + goto exit; + + ALOGI("%s: effect type: %08x", __func__, desc.type.timeLow); + + if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) { + in->need_echo_reference = false; + do_input_standby(in); + } + +exit: + + ALOGW_IF(status != 0, "%s: error %d", __func__, status); + pthread_mutex_unlock(&in->lock); + pthread_mutex_unlock(&in->dev->lock); + return status; +} + +static int adev_open_output_stream(struct audio_hw_device *dev, + audio_io_handle_t handle, + audio_devices_t devices, + audio_output_flags_t flags, + struct audio_config *config, + struct audio_stream_out **stream_out) +{ + struct m0_audio_device *ladev = (struct m0_audio_device *)dev; + struct m0_stream_out *out; + int ret; + int output_type; + *stream_out = NULL; + + out = (struct m0_stream_out *)calloc(1, sizeof(struct m0_stream_out)); + if (!out) + return -ENOMEM; + + out->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO; + out->channel_mask = AUDIO_CHANNEL_OUT_STEREO; + + if (ladev->outputs[OUTPUT_DEEP_BUF] != NULL) { + ret = -ENOSYS; + goto err_open; + } + output_type = OUTPUT_DEEP_BUF; + out->channel_mask = AUDIO_CHANNEL_OUT_STEREO; + out->stream.common.get_buffer_size = out_get_buffer_size_deep_buffer; + out->stream.common.get_sample_rate = out_get_sample_rate; + out->stream.get_latency = out_get_latency_deep_buffer; + out->stream.write = out_write_deep_buffer; + + ret = create_resampler(DEFAULT_OUT_SAMPLING_RATE, + MM_FULL_POWER_SAMPLING_RATE, + 2, + RESAMPLER_QUALITY_DEFAULT, + NULL, + &out->resampler); + if (ret != 0) + goto err_open; + + out->stream.common.set_sample_rate = out_set_sample_rate; + out->stream.common.get_channels = out_get_channels; + out->stream.common.get_format = out_get_format; + out->stream.common.set_format = out_set_format; + out->stream.common.standby = out_standby; + out->stream.common.dump = out_dump; + out->stream.common.set_parameters = out_set_parameters; + out->stream.common.get_parameters = out_get_parameters; + out->stream.common.add_audio_effect = out_add_audio_effect; + out->stream.common.remove_audio_effect = out_remove_audio_effect; + out->stream.set_volume = out_set_volume; + out->stream.get_render_position = out_get_render_position; + + out->dev = ladev; + out->standby = 1; + + /* FIXME: when we support multiple output devices, we will want to + * do the following: + * adev->out_device = out->device; + * select_output_device(adev); + * This is because out_set_parameters() with a route is not + * guaranteed to be called after an output stream is opened. */ + + config->format = out->stream.common.get_format(&out->stream.common); + config->channel_mask = out->stream.common.get_channels(&out->stream.common); + config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common); + + *stream_out = &out->stream; + ladev->outputs[output_type] = out; + + return 0; + +err_open: + free(out); + return ret; +} + +static void adev_close_output_stream(struct audio_hw_device *dev, + struct audio_stream_out *stream) +{ + struct m0_audio_device *ladev = (struct m0_audio_device *)dev; + struct m0_stream_out *out = (struct m0_stream_out *)stream; + int i; + + out_standby(&stream->common); + for (i = 0; i < OUTPUT_TOTAL; i++) { + if (ladev->outputs[i] == out) { + ladev->outputs[i] = NULL; + break; + } + } + + if (out->buffer) + free(out->buffer); + if (out->resampler) + release_resampler(out->resampler); + free(stream); +} + +static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) +{ + struct m0_audio_device *adev = (struct m0_audio_device *)dev; + struct str_parms *parms; + char *str; + char value[32]; + int ret; + + parms = str_parms_create_str(kvpairs); + ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value)); + if (ret >= 0) { + int tty_mode; + + if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0) + tty_mode = TTY_MODE_OFF; + else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0) + tty_mode = TTY_MODE_VCO; + else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0) + tty_mode = TTY_MODE_HCO; + else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0) + tty_mode = TTY_MODE_FULL; + else + return -EINVAL; + + pthread_mutex_lock(&adev->lock); + if (tty_mode != adev->tty_mode) { + adev->tty_mode = tty_mode; + if (adev->mode == AUDIO_MODE_IN_CALL) + select_output_device(adev); + } + pthread_mutex_unlock(&adev->lock); + } + + ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value)); + if (ret >= 0) { + if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) + adev->bluetooth_nrec = true; + else + adev->bluetooth_nrec = false; + } + + ret = str_parms_get_str(parms, "screen_off", value, sizeof(value)); + if (ret >= 0) { + if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) + adev->screen_off = false; + else + adev->screen_off = true; + } + + str_parms_destroy(parms); + return ret; +} + +static char * adev_get_parameters(const struct audio_hw_device *dev, + const char *keys) +{ + return strdup(""); +} + +static int adev_init_check(const struct audio_hw_device *dev) +{ + return 0; +} + +static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) +{ + struct m0_audio_device *adev = (struct m0_audio_device *)dev; + + adev->voice_volume = volume; + + if (adev->mode == AUDIO_MODE_IN_CALL) + ril_set_call_volume(&adev->ril, SOUND_TYPE_VOICE, volume); + + return 0; +} + +static int adev_set_master_volume(struct audio_hw_device *dev, float volume) +{ + return -ENOSYS; +} + +static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) +{ + struct m0_audio_device *adev = (struct m0_audio_device *)dev; + + pthread_mutex_lock(&adev->lock); + if (adev->mode != mode) { + adev->mode = mode; + select_mode(adev); + } + pthread_mutex_unlock(&adev->lock); + + return 0; +} + +static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) +{ + struct m0_audio_device *adev = (struct m0_audio_device *)dev; + + adev->mic_mute = state; + + return 0; +} + +static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) +{ + struct m0_audio_device *adev = (struct m0_audio_device *)dev; + + *state = adev->mic_mute; + + return 0; +} + +static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, + const struct audio_config *config) +{ + size_t size; + int channel_count = popcount(config->channel_mask); + if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) + return 0; + + return get_input_buffer_size(config->sample_rate, config->format, channel_count); +} + +static int adev_open_input_stream(struct audio_hw_device *dev, + audio_io_handle_t handle, + audio_devices_t devices, + struct audio_config *config, + struct audio_stream_in **stream_in) +{ + struct m0_audio_device *ladev = (struct m0_audio_device *)dev; + struct m0_stream_in *in; + int ret; + int channel_count = popcount(config->channel_mask); + + *stream_in = NULL; + + if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) + return -EINVAL; + + in = (struct m0_stream_in *)calloc(1, sizeof(struct m0_stream_in)); + if (!in) + return -ENOMEM; + + in->stream.common.get_sample_rate = in_get_sample_rate; + in->stream.common.set_sample_rate = in_set_sample_rate; + in->stream.common.get_buffer_size = in_get_buffer_size; + in->stream.common.get_channels = in_get_channels; + in->stream.common.get_format = in_get_format; + in->stream.common.set_format = in_set_format; + in->stream.common.standby = in_standby; + in->stream.common.dump = in_dump; + in->stream.common.set_parameters = in_set_parameters; + in->stream.common.get_parameters = in_get_parameters; + in->stream.common.add_audio_effect = in_add_audio_effect; + in->stream.common.remove_audio_effect = in_remove_audio_effect; + in->stream.set_gain = in_set_gain; + in->stream.read = in_read; + in->stream.get_input_frames_lost = in_get_input_frames_lost; + + in->requested_rate = config->sample_rate; + + memcpy(&in->config, &pcm_config_capture, sizeof(pcm_config_capture)); + in->config.channels = channel_count; + + in->main_channels = config->channel_mask; + + /* initialisation of preprocessor structure array is implicit with the calloc. + * same for in->aux_channels and in->aux_channels_changed */ + + if (in->requested_rate != in->config.rate) { + in->buf_provider.get_next_buffer = get_next_buffer; + in->buf_provider.release_buffer = release_buffer; + + ret = create_resampler(in->config.rate, + in->requested_rate, + in->config.channels, + RESAMPLER_QUALITY_DEFAULT, + &in->buf_provider, + &in->resampler); + if (ret != 0) { + ret = -EINVAL; + goto err; + } + } + + in->dev = ladev; + in->standby = 1; + in->device = devices & ~AUDIO_DEVICE_BIT_IN; + + *stream_in = &in->stream; + return 0; + +err: + if (in->resampler) + release_resampler(in->resampler); + + free(in); + return ret; +} + +static void adev_close_input_stream(struct audio_hw_device *dev, + struct audio_stream_in *stream) +{ + struct m0_stream_in *in = (struct m0_stream_in *)stream; + int i; + + in_standby(&stream->common); + + for (i = 0; i < in->num_preprocessors; i++) { + free(in->preprocessors[i].channel_configs); + } + + free(in->read_buf); + if (in->resampler) { + release_resampler(in->resampler); + } + if (in->proc_buf_in) + free(in->proc_buf_in); + if (in->proc_buf_out) + free(in->proc_buf_out); + if (in->ref_buf) + free(in->ref_buf); + + free(stream); + return; +} + +static int adev_dump(const audio_hw_device_t *device, int fd) +{ + return 0; +} + +static int adev_close(hw_device_t *device) +{ + struct m0_audio_device *adev = (struct m0_audio_device *)device; + + /* RIL */ + ril_close(&adev->ril); + + mixer_close(adev->mixer); + free(device); + return 0; +} + +struct config_parse_state { + struct m0_audio_device *adev; + struct m0_dev_cfg *dev; + bool on; + + struct route_setting *path; + unsigned int path_len; +}; + +static const struct { + int mask; + const char *name; +} dev_names[] = { + { AUDIO_DEVICE_OUT_SPEAKER, "speaker" }, + { AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "headphone" }, + { AUDIO_DEVICE_OUT_EARPIECE, "earpiece" }, + { AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, "analog-dock" }, + { AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, "digital-dock" }, + { AUDIO_DEVICE_OUT_ALL_SCO, "sco-out" }, + + { AUDIO_DEVICE_IN_BUILTIN_MIC, "builtin-mic" }, + { AUDIO_DEVICE_IN_BACK_MIC, "back-mic" }, + { AUDIO_DEVICE_IN_WIRED_HEADSET, "headset-in" }, + { AUDIO_DEVICE_IN_ALL_SCO, "sco-in" }, +}; + +static void adev_config_start(void *data, const XML_Char *elem, + const XML_Char **attr) +{ + struct config_parse_state *s = data; + struct m0_dev_cfg *dev_cfg; + const XML_Char *name = NULL; + const XML_Char *val = NULL; + unsigned int i, j; + + for (i = 0; attr[i]; i += 2) { + if (strcmp(attr[i], "name") == 0) + name = attr[i + 1]; + + if (strcmp(attr[i], "val") == 0) + val = attr[i + 1]; + } + + if (strcmp(elem, "device") == 0) { + if (!name) { + ALOGE("Unnamed device\n"); + return; + } + + for (i = 0; i < sizeof(dev_names) / sizeof(dev_names[0]); i++) { + if (strcmp(dev_names[i].name, name) == 0) { + ALOGI("Allocating device %s\n", name); + dev_cfg = realloc(s->adev->dev_cfgs, + (s->adev->num_dev_cfgs + 1) + * sizeof(*dev_cfg)); + if (!dev_cfg) { + ALOGE("Unable to allocate dev_cfg\n"); + return; + } + + s->dev = &dev_cfg[s->adev->num_dev_cfgs]; + memset(s->dev, 0, sizeof(*s->dev)); + s->dev->mask = dev_names[i].mask; + + s->adev->dev_cfgs = dev_cfg; + s->adev->num_dev_cfgs++; + } + } + + } else if (strcmp(elem, "path") == 0) { + if (s->path_len) + ALOGW("Nested paths\n"); + + /* If this a path for a device it must have a role */ + if (s->dev) { + /* Need to refactor a bit... */ + if (strcmp(name, "on") == 0) { + s->on = true; + } else if (strcmp(name, "off") == 0) { + s->on = false; + } else { + ALOGW("Unknown path name %s\n", name); + } + } + + } else if (strcmp(elem, "ctl") == 0) { + struct route_setting *r; + + if (!name) { + ALOGE("Unnamed control\n"); + return; + } + + if (!val) { + ALOGE("No value specified for %s\n", name); + return; + } + + ALOGV("Parsing control %s => %s\n", name, val); + + r = realloc(s->path, sizeof(*r) * (s->path_len + 1)); + if (!r) { + ALOGE("Out of memory handling %s => %s\n", name, val); + return; + } + + r[s->path_len].ctl_name = strdup(name); + r[s->path_len].strval = NULL; + + /* This can be fooled but it'll do */ + r[s->path_len].intval = atoi(val); + if (!r[s->path_len].intval && strcmp(val, "0") != 0) + r[s->path_len].strval = strdup(val); + + s->path = r; + s->path_len++; + } +} + +static void adev_config_end(void *data, const XML_Char *name) +{ + struct config_parse_state *s = data; + unsigned int i; + + if (strcmp(name, "path") == 0) { + if (!s->path_len) + ALOGW("Empty path\n"); + + if (!s->dev) { + ALOGV("Applying %d element default route\n", s->path_len); + + set_route_by_array(s->adev->mixer, s->path, s->path_len); + + for (i = 0; i < s->path_len; i++) { + free(s->path[i].ctl_name); + free(s->path[i].strval); + } + + free(s->path); + + /* Refactor! */ + } else if (s->on) { + ALOGV("%d element on sequence\n", s->path_len); + s->dev->on = s->path; + s->dev->on_len = s->path_len; + + } else { + ALOGV("%d element off sequence\n", s->path_len); + + /* Apply it, we'll reenable anything that's wanted later */ + set_route_by_array(s->adev->mixer, s->path, s->path_len); + + s->dev->off = s->path; + s->dev->off_len = s->path_len; + } + + s->path_len = 0; + s->path = NULL; + + } else if (strcmp(name, "device") == 0) { + s->dev = NULL; + } +} + +static int adev_config_parse(struct m0_audio_device *adev) +{ + struct config_parse_state s; + FILE *f; + XML_Parser p; + int ret = 0; + bool eof = false; + int len; + char buf[1024]; + + ALOGV("Reading configuration from %s\n", CONFIG_FILE); + f = fopen(CONFIG_FILE, "r"); + if (!f) { + ALOGE("Failed to open %s\n", CONFIG_FILE); + return -ENODEV; + } + + p = XML_ParserCreate(NULL); + if (!p) { + ALOGE("Failed to create XML parser\n"); + ret = -ENOMEM; + goto out; + } + + memset(&s, 0, sizeof(s)); + s.adev = adev; + XML_SetUserData(p, &s); + + XML_SetElementHandler(p, adev_config_start, adev_config_end); + + while (!eof) { + len = fread(buf, 1, sizeof(buf), f); + if (ferror(f)) { + ALOGE("I/O error reading config\n"); + ret = -EIO; + goto out_parser; + } + eof = feof(f); + + if (XML_Parse(p, buf, len, eof) == XML_STATUS_ERROR) { + ALOGE("Parse error at line %u:\n%s\n", + (unsigned int)XML_GetCurrentLineNumber(p), + XML_ErrorString(XML_GetErrorCode(p))); + ret = -EINVAL; + goto out_parser; + } + } + + out_parser: + XML_ParserFree(p); + out: + fclose(f); + + return ret; +} + +static int adev_open(const hw_module_t* module, const char* name, + hw_device_t** device) +{ + struct m0_audio_device *adev; + int ret; + + if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) + return -EINVAL; + + adev = calloc(1, sizeof(struct m0_audio_device)); + if (!adev) + return -ENOMEM; + + adev->hw_device.common.tag = HARDWARE_DEVICE_TAG; + adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0; + adev->hw_device.common.module = (struct hw_module_t *) module; + adev->hw_device.common.close = adev_close; + + adev->hw_device.init_check = adev_init_check; + adev->hw_device.set_voice_volume = adev_set_voice_volume; + adev->hw_device.set_master_volume = adev_set_master_volume; + adev->hw_device.set_mode = adev_set_mode; + adev->hw_device.set_mic_mute = adev_set_mic_mute; + adev->hw_device.get_mic_mute = adev_get_mic_mute; + adev->hw_device.set_parameters = adev_set_parameters; + adev->hw_device.get_parameters = adev_get_parameters; + adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size; + adev->hw_device.open_output_stream = adev_open_output_stream; + adev->hw_device.close_output_stream = adev_close_output_stream; + adev->hw_device.open_input_stream = adev_open_input_stream; + adev->hw_device.close_input_stream = adev_close_input_stream; + adev->hw_device.dump = adev_dump; + + adev->mixer = mixer_open(CARD_DEFAULT); + if (!adev->mixer) { + free(adev); + ALOGE("Unable to open the mixer, aborting."); + return -EINVAL; + } + + /* +30db boost for mics */ + adev->mixer_ctls.mixinl_in1l_volume = mixer_get_ctl_by_name(adev->mixer, "MIXINL IN1L Volume"); + adev->mixer_ctls.mixinl_in2l_volume = mixer_get_ctl_by_name(adev->mixer, "MIXINL IN2L Volume"); + + ret = adev_config_parse(adev); + if (ret != 0) + goto err_mixer; + + /* Set the default route before the PCM stream is opened */ + pthread_mutex_lock(&adev->lock); + adev->mode = AUDIO_MODE_NORMAL; + adev->out_device = AUDIO_DEVICE_OUT_SPEAKER; + adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; + select_devices(adev); + + adev->pcm_modem_dl = NULL; + adev->pcm_modem_ul = NULL; + adev->voice_volume = 1.0f; + adev->tty_mode = TTY_MODE_OFF; + adev->bluetooth_nrec = true; + adev->wb_amr = 0; + + /* RIL */ + ril_open(&adev->ril); + pthread_mutex_unlock(&adev->lock); + /* register callback for wideband AMR setting */ + ril_register_set_wb_amr_callback(audio_set_wb_amr_callback, (void *)adev); + + *device = &adev->hw_device.common; + + return 0; + +err_mixer: + mixer_close(adev->mixer); +err: + return -EINVAL; +} + +static struct hw_module_methods_t hal_module_methods = { + .open = adev_open, +}; + +struct audio_module HAL_MODULE_INFO_SYM = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = AUDIO_MODULE_API_VERSION_0_1, + .hal_api_version = HARDWARE_HAL_API_VERSION, + .id = AUDIO_HARDWARE_MODULE_ID, + .name = "M0 audio HW HAL", + .author = "The CyanogenMod Project", + .methods = &hal_module_methods, + }, +}; diff --git a/audio/audio_hw.h b/audio/audio_hw.h new file mode 100644 index 0000000..246cba8 --- /dev/null +++ b/audio/audio_hw.h @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2012 Wolfson Microelectronics plc + * Copyright (C) 2012 The CyanogenMod Project + * Daniel Hillenbrand + * Guillaume "XpLoDWilD" Lesniak + * + * 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 CONFIG_FILE "/system/etc/sound/tiny_hw.xml" + +/* ALSA cards for WM1811 */ +#define CARD_DEFAULT 0 + +#define PORT_PLAYBACK 0 +#define PORT_MODEM 1 +#define PORT_BT 2 +#define PORT_CAPTURE 3 + +#define PCM_WRITE pcm_write + +#define PLAYBACK_PERIOD_SIZE 880 +#define PLAYBACK_PERIOD_COUNT 8 +#define PLAYBACK_SHORT_PERIOD_COUNT 2 + +#define CAPTURE_PERIOD_SIZE 1024 +#define CAPTURE_PERIOD_COUNT 4 + +#define SHORT_PERIOD_SIZE 192 + +// +// deep buffer +// +/* screen on */ +#define DEEP_BUFFER_SHORT_PERIOD_SIZE 1056 +#define PLAYBACK_DEEP_BUFFER_SHORT_PERIOD_COUNT 4 +/* screen off */ +#define DEEP_BUFFER_LONG_PERIOD_SIZE 880 +#define PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT 8 + + +/* minimum sleep time in out_write() when write threshold is not reached */ +#define MIN_WRITE_SLEEP_US 5000 + +#define RESAMPLER_BUFFER_FRAMES (PLAYBACK_PERIOD_SIZE * 2) +#define RESAMPLER_BUFFER_SIZE (4 * RESAMPLER_BUFFER_FRAMES) + +#define DEFAULT_OUT_SAMPLING_RATE 44100 +#define MM_LOW_POWER_SAMPLING_RATE 44100 +#define MM_FULL_POWER_SAMPLING_RATE 44100 +#define DEFAULT_IN_SAMPLING_RATE 44100 + +/* sampling rate when using VX port for narrow band */ +#define VX_NB_SAMPLING_RATE 8000 +/* sampling rate when using VX port for wide band */ +#define VX_WB_SAMPLING_RATE 16000 + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +#define STRING_TO_ENUM(string) { #string, string } + +struct string_to_enum { + const char *name; + uint32_t value; +}; + +const struct string_to_enum out_channels_name_to_enum_table[] = { + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), +}; + +enum pcm_type { + PCM_NORMAL = 0, + PCM_SPDIF, + PCM_HDMI, + PCM_TOTAL, +}; + +enum output_type { + OUTPUT_DEEP_BUF, // deep PCM buffers output stream + OUTPUT_LOW_LATENCY, // low latency output stream + OUTPUT_HDMI, + OUTPUT_TOTAL +}; + +enum tty_modes { + TTY_MODE_OFF, + TTY_MODE_VCO, + TTY_MODE_HCO, + TTY_MODE_FULL +}; + +struct mixer_ctls +{ + struct mixer_ctl *mixinl_in1l_volume; + struct mixer_ctl *mixinl_in2l_volume; +}; + +struct route_setting +{ + char *ctl_name; + int intval; + char *strval; +}; + +struct route_setting voicecall_default[] = { + { .ctl_name = "AIF2DACL Source", .intval = 0, }, + { .ctl_name = "AIF2DACR Source", .intval = 0, }, + { .ctl_name = "AIF2 Mode", .intval = 0, }, + { .ctl_name = "DAC1L Mixer AIF1.1 Switch", .intval = 1, }, + { .ctl_name = "DAC1R Mixer AIF1.1 Switch", .intval = 1, }, + { .ctl_name = "DAC1L Mixer AIF2 Switch", .intval = 1, }, + { .ctl_name = "DAC1R Mixer AIF2 Switch", .intval = 1, }, + { .ctl_name = "AIF2DAC Mux", .strval = "AIF2DACDAT", }, + { .ctl_name = NULL, }, +}; + +struct route_setting voicecall_default_disable[] = { + { .ctl_name = "AIF2DACL Source", .intval = 0, }, + { .ctl_name = "AIF2DACR Source", .intval = 1, }, + { .ctl_name = "AIF2 Mode", .intval = 0, }, + { .ctl_name = "DAC1L Mixer AIF2 Switch", .intval = 0, }, + { .ctl_name = "DAC1R Mixer AIF2 Switch", .intval = 0, }, + { .ctl_name = "AIF2DAC Mux", .strval = "AIF3DACDAT", }, + { .ctl_name = "Main Mic Switch", .intval = 0, }, + { .ctl_name = "MIXINL IN1L Switch", .intval = 0, }, + { .ctl_name = "Sub Mic Switch", .intval = 0, }, + { .ctl_name = "MIXINR IN1R Switch", .intval = 0, }, + { .ctl_name = NULL, }, +}; + +struct route_setting default_input[] = { + { .ctl_name = "Main Mic Switch", .intval = 1, }, + { .ctl_name = "IN1L Volume", .intval = 30, }, + { .ctl_name = "MIXINL IN1L Switch", .intval = 1, }, + { .ctl_name = "MIXINL IN1L Volume", .intval = 0, }, + { .ctl_name = "AIF1ADC1 HPF Mode", .intval = 0, }, + { .ctl_name = "AIF1ADC1 HPF Switch", .intval = 1, }, + { .ctl_name = NULL, }, +}; + +struct route_setting default_input_disable[] = { + { .ctl_name = "Main Mic Switch", .intval = 0, }, + { .ctl_name = "IN1L Volume", .intval = 22, }, + { .ctl_name = "MIXINL IN1L Switch", .intval = 0, }, + { .ctl_name = "AIF1ADC1 HPF Switch", .intval = 0, }, + { .ctl_name = NULL, }, +}; + +struct route_setting headset_input[] = { + { .ctl_name = "MIXINL IN1L Switch", .intval = 0, }, + { .ctl_name = "MIXINR IN1R Switch", .intval = 0, }, + { .ctl_name = "Headset Mic Switch", .intval = 1, }, + { .ctl_name = "IN2L Volume", .intval = 18, }, + { .ctl_name = "MIXINL IN2L Switch", .intval = 1, }, + { .ctl_name = "MIXINL IN2L Volume", .intval = 0, }, + { .ctl_name = "AIF1ADC1 HPF Mode", .intval = 1, }, + { .ctl_name = "AIF1ADC1 HPF Switch", .intval = 1, }, + { .ctl_name = "AIF1ADC1 Volume", .intval = 96, }, + { .ctl_name = "AIF1ADCL Source", .intval = 0, }, + { .ctl_name = "AIF1ADCR Source", .intval = 0, }, + { .ctl_name = "AIF2ADCL Source", .intval = 0, }, + { .ctl_name = NULL, }, +}; + +struct route_setting headset_input_disable[] = { + { .ctl_name = "Headset Mic Switch", .intval = 0, }, + { .ctl_name = "MIXINL IN2L Switch", .intval = 0, }, + { .ctl_name = "AIF1ADC1 HPF Mode", .intval = 0, }, + { .ctl_name = "AIF1ADC1 HPF Switch", .intval = 0, }, + { .ctl_name = NULL, }, +}; + +struct route_setting bt_output[] = { + { .ctl_name = "DAC1L Mixer AIF1.1 Switch", .intval = 1, }, + { .ctl_name = "DAC1R Mixer AIF1.1 Switch", .intval = 1, }, + { .ctl_name = "AIF3ADC Mux", .intval = 1, }, + { .ctl_name = "AIF2DAC2L Mixer AIF1.1 Switch", .intval = 1, }, + { .ctl_name = "AIF2DAC2R Mixer AIF1.1 Switch", .intval = 1, }, + { .ctl_name = "AIF2DAC Volume", .intval = 96, }, + { .ctl_name = "DAC2 Volume", .intval = 96, }, + { .ctl_name = "AIF2ADC Volume", .intval = 96, }, + { .ctl_name = "Speaker Mixer Volume", .intval = 1, }, + { .ctl_name = "MIXINL IN2L Volume", .intval = 1, }, + { .ctl_name = "IN1L Volume", .intval = 25, }, + { .ctl_name = "IN1R Volume", .intval = 25, }, + { .ctl_name = "Speaker Boost Volume", .intval = 4, }, + { .ctl_name = "LINEOUT1N Switch", .intval = 0, }, + { .ctl_name = "LINEOUT1P Switch", .intval = 0, }, + { .ctl_name = "AIF2DACR Source", .intval = 0, }, + { .ctl_name = "AIF1ADC1 HPF Switch", .intval = 0, }, + { .ctl_name = "AIF2ADC HPF Mode", .intval = 1, }, + { .ctl_name = "AIF2ADC HPF Switch", .intval = 1, }, + { .ctl_name = "AIF2DAC Mux", .strval = "AIF2DACDAT", }, + { .ctl_name = "AIF2DAC2R Mixer AIF2 Switch", .intval = 1, }, + { .ctl_name = "AIF2DAC2L Mixer AIF2 Switch", .intval = 1, }, + { .ctl_name = NULL, }, +}; + +struct route_setting bt_input[] = { + { .ctl_name = "AIF2ADC Mux", .intval = 1, }, + { .ctl_name = "AIF1ADCL Source", .intval = 0, }, + { .ctl_name = "AIF1ADCR Source", .intval = 1, }, + { .ctl_name = "AIF2ADCL Source", .intval = 0, }, + { .ctl_name = "AIF2ADCR Source", .intval = 1, }, + { .ctl_name = "DAC1L Mixer AIF2 Switch", .intval = 1, }, + { .ctl_name = "DAC1R Mixer AIF2 Switch", .intval = 1, }, + { .ctl_name = "AIF1ADC1R Mixer AIF2 Switch", .intval = 1, }, + { .ctl_name = "AIF1ADC1L Mixer AIF2 Switch", .intval = 1, }, + { .ctl_name = "AIF1ADC1 Volume", .intval = 96, }, + { .ctl_name = "AIF2DAC Volume", .intval = 96, }, + { .ctl_name = NULL, }, +}; + +struct route_setting bt_disable[] = { + { .ctl_name = "AIF2ADC Mux", .intval = 0, }, + { .ctl_name = "MIXINL IN2L Volume", .intval = 0, }, + { .ctl_name = "LINEOUT1N Switch", .intval = 1, }, + { .ctl_name = "LINEOUT1P Switch", .intval = 1, }, + { .ctl_name = "AIF2ADC HPF Mode", .intval = 0, }, + { .ctl_name = "AIF2ADC HPF Switch", .intval = 0, }, + { .ctl_name = "AIF2DAC2R Mixer AIF2 Switch", .intval = 0, }, + { .ctl_name = "AIF2DAC2L Mixer AIF2 Switch", .intval = 0, }, + { .ctl_name = "AIF1ADC1R Mixer AIF2 Switch", .intval = 0, }, + { .ctl_name = "AIF1ADC1L Mixer AIF2 Switch", .intval = 0, }, + { .ctl_name = NULL, }, +}; diff --git a/audio/ril_interface.c b/audio/ril_interface.c new file mode 100755 index 0000000..89a0aef --- /dev/null +++ b/audio/ril_interface.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2011 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 ALOG_TAG "audio_hw_primary" +/*#define ALOG_NDEBUG 0*/ + +#include +#include + +#include +#include + +#include "ril_interface.h" + +#define VOLUME_STEPS_DEFAULT "5" +#define VOLUME_STEPS_PROPERTY "ro.config.vc_call_vol_steps" + +/* Function pointers */ +void *(*_ril_open_client)(void); +int (*_ril_close_client)(void *); +int (*_ril_connect)(void *); +int (*_ril_is_connected)(void *); +int (*_ril_disconnect)(void *); +int (*_ril_set_call_volume)(void *, enum ril_sound_type, int); +int (*_ril_set_call_audio_path)(void *, enum ril_audio_path); +int (*_ril_set_call_clock_sync)(void *, enum ril_clock_state); +int (*_ril_register_unsolicited_handler)(void *, int, void *); +int (*_ril_get_wb_amr)(void *, void *); + +/* Audio WB AMR callback */ +void (*_audio_set_wb_amr_callback)(void *, int); +void *callback_data = NULL; + +void ril_register_set_wb_amr_callback(void *function, void *data) +{ + _audio_set_wb_amr_callback = function; + callback_data = data; +} + +/* This is the callback function that the RIL uses to +set the wideband AMR state */ +static int ril_set_wb_amr_callback(void *ril_client, + const void *data, + size_t datalen) +{ + int enable = ((int *)data)[0]; + + if (!callback_data || !_audio_set_wb_amr_callback) + return -1; + + _audio_set_wb_amr_callback(callback_data, enable); + + return 0; +} + +static int ril_connect_if_required(struct ril_handle *ril) +{ + if (_ril_is_connected(ril->client)) + return 0; + + if (_ril_connect(ril->client) != RIL_CLIENT_ERR_SUCCESS) { + ALOGE("ril_connect() failed"); + return -1; + } + + /* get wb amr status to set pcm samplerate depending on + wb amr status when ril is connected. */ + if(_ril_get_wb_amr) + _ril_get_wb_amr(ril->client, ril_set_wb_amr_callback); + + return 0; +} + +int ril_open(struct ril_handle *ril) +{ + char property[PROPERTY_VALUE_MAX]; + + if (!ril) + return -1; + + ril->handle = dlopen(RIL_CLIENT_LIBPATH, RTLD_NOW); + + if (!ril->handle) { + ALOGE("Cannot open '%s'", RIL_CLIENT_LIBPATH); + return -1; + } + + _ril_open_client = dlsym(ril->handle, "OpenClient_RILD"); + _ril_close_client = dlsym(ril->handle, "CloseClient_RILD"); + _ril_connect = dlsym(ril->handle, "Connect_RILD"); + _ril_is_connected = dlsym(ril->handle, "isConnected_RILD"); + _ril_disconnect = dlsym(ril->handle, "Disconnect_RILD"); + _ril_set_call_volume = dlsym(ril->handle, "SetCallVolume"); + _ril_set_call_audio_path = dlsym(ril->handle, "SetCallAudioPath"); + _ril_set_call_clock_sync = dlsym(ril->handle, "SetCallClockSync"); + _ril_register_unsolicited_handler = dlsym(ril->handle, + "RegisterUnsolicitedHandler"); + /* since this function is not supported in all RILs, don't require it */ + _ril_get_wb_amr = dlsym(ril->handle, "GetWB_AMR"); + + if (!_ril_open_client || !_ril_close_client || !_ril_connect || + !_ril_is_connected || !_ril_disconnect || !_ril_set_call_volume || + !_ril_set_call_audio_path || !_ril_set_call_clock_sync || + !_ril_register_unsolicited_handler) { + ALOGE("Cannot get symbols from '%s'", RIL_CLIENT_LIBPATH); + dlclose(ril->handle); + return -1; + } + + ril->client = _ril_open_client(); + if (!ril->client) { + ALOGE("ril_open_client() failed"); + dlclose(ril->handle); + return -1; + } + + /* register the wideband AMR callback */ + _ril_register_unsolicited_handler(ril->client, RIL_UNSOL_WB_AMR_STATE, + ril_set_wb_amr_callback); + + property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT); + ril->volume_steps_max = atoi(property); + /* this catches the case where VOLUME_STEPS_PROPERTY does not contain + an integer */ + if (ril->volume_steps_max == 0) + ril->volume_steps_max = atoi(VOLUME_STEPS_DEFAULT); + + return 0; +} + +int ril_close(struct ril_handle *ril) +{ + if (!ril || !ril->handle || !ril->client) + return -1; + + if ((_ril_disconnect(ril->client) != RIL_CLIENT_ERR_SUCCESS) || + (_ril_close_client(ril->client) != RIL_CLIENT_ERR_SUCCESS)) { + ALOGE("ril_disconnect() or ril_close_client() failed"); + return -1; + } + + dlclose(ril->handle); + return 0; +} + +int ril_set_call_volume(struct ril_handle *ril, enum ril_sound_type sound_type, + float volume) +{ + if (ril_connect_if_required(ril)) + return 0; + + return _ril_set_call_volume(ril->client, sound_type, + (int)(volume * ril->volume_steps_max)); +} + +int ril_set_call_audio_path(struct ril_handle *ril, enum ril_audio_path path) +{ + if (ril_connect_if_required(ril)) + return 0; + + return _ril_set_call_audio_path(ril->client, path); +} + +int ril_set_call_clock_sync(struct ril_handle *ril, enum ril_clock_state state) +{ + if (ril_connect_if_required(ril)) + return 0; + + return _ril_set_call_clock_sync(ril->client, state); +} diff --git a/audio/ril_interface.h b/audio/ril_interface.h new file mode 100755 index 0000000..676772c --- /dev/null +++ b/audio/ril_interface.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2011 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 RIL_INTERFACE_H +#define RIL_INTERFACE_H + +#define RIL_CLIENT_LIBPATH "libsecril-client.so" + +#define RIL_CLIENT_ERR_SUCCESS 0 +#define RIL_CLIENT_ERR_AGAIN 1 +#define RIL_CLIENT_ERR_INIT 2 // Client is not initialized +#define RIL_CLIENT_ERR_INVAL 3 // Invalid value +#define RIL_CLIENT_ERR_CONNECT 4 // Connection error +#define RIL_CLIENT_ERR_IO 5 // IO error +#define RIL_CLIENT_ERR_RESOURCE 6 // Resource not available +#define RIL_CLIENT_ERR_UNKNOWN 7 + +#define RIL_OEM_UNSOL_RESPONSE_BASE 11000 // RIL response base index +#define RIL_UNSOL_WB_AMR_STATE \ + (RIL_OEM_UNSOL_RESPONSE_BASE + 17) // RIL AMR state index + +struct ril_handle +{ + void *handle; + void *client; + int volume_steps_max; +}; + +enum ril_sound_type { + SOUND_TYPE_VOICE, + SOUND_TYPE_SPEAKER, + SOUND_TYPE_HEADSET, + SOUND_TYPE_BTVOICE +}; + +enum ril_audio_path { + SOUND_AUDIO_PATH_HANDSET, + SOUND_AUDIO_PATH_HEADSET, + SOUND_AUDIO_PATH_SPEAKER, + SOUND_AUDIO_PATH_BLUETOOTH, + SOUND_AUDIO_PATH_BLUETOOTH_NO_NR, + SOUND_AUDIO_PATH_HEADPHONE +}; + +enum ril_clock_state { + SOUND_CLOCK_STOP, + SOUND_CLOCK_START +}; + +/* Function prototypes */ +int ril_open(struct ril_handle *ril); +int ril_close(struct ril_handle *ril); +int ril_set_call_volume(struct ril_handle *ril, enum ril_sound_type sound_type, + float volume); +int ril_set_call_audio_path(struct ril_handle *ril, enum ril_audio_path path); +int ril_set_call_clock_sync(struct ril_handle *ril, enum ril_clock_state state); +void ril_register_set_wb_amr_callback(void *function, void *data); +#endif + diff --git a/bluetooth/bdroid_buildcfg.h b/bluetooth/bdroid_buildcfg.h new file mode 100755 index 0000000..283a9ed --- /dev/null +++ b/bluetooth/bdroid_buildcfg.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2012 The CyanogenMod 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 BTM_DEF_LOCAL_NAME "GT-N5100" + +// Networking, Capturing, Object Transfer +// MAJOR CLASS: COMPUTER +// MINOR CLASS: LAPTOP +#define BTA_DM_COD {0x1A, 0x01, 0x0C} + +#define BTIF_HF_SERVICES (BTA_HSP_SERVICE_MASK) +#define BTIF_HF_SERVICE_NAMES { BTIF_HSAG_SERVICE_NAME } +#define PAN_NAP_DISABLED TRUE +#define BLE_INCLUDED FALSE +#define BTA_GATT_INCLUDED FALSE +#define SMP_INCLUDED FALSE + + +#endif diff --git a/bluetooth/vnd_n5100.txt b/bluetooth/vnd_n5100.txt new file mode 100755 index 0000000..b680ecb --- /dev/null +++ b/bluetooth/vnd_n5100.txt @@ -0,0 +1,14 @@ +BLUETOOTH_UART_DEVICE_PORT = "/dev/ttySAC0" +FW_PATCHFILE_LOCATION = "/system/bin/" +LPM_IDLE_TIMEOUT_MULTIPLE = 5 +BTVND_DBG = FALSE +BTHW_DBG = TRUE +VNDUSERIAL_DBG = FALSE +UPIO_DBG = FALSE +UART_TARGET_BAUD_RATE = 4000000 +FW_PATCH_SETTLEMENT_DELAY_MS = 50 +SCO_USE_I2S_INTERFACE = TRUE +SCO_I2SPCM_IF_MODE = 1 +SCO_I2SPCM_IF_ROLE = 0 +SCO_I2SPCM_IF_SAMPLE_RATE = 0 +SCO_I2SPCM_IF_CLOCK_RATE = 0 diff --git a/camera/Android.mk b/camera/Android.mk new file mode 100644 index 0000000..52d6b4e --- /dev/null +++ b/camera/Android.mk @@ -0,0 +1,54 @@ +# +# Copyright (C) 2013 Paul Kocialkowski +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +ifneq ($(filter n5100 n5110,$(TARGET_DEVICE)),) + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + exynos_camera.c \ + exynos_exif.c \ + exynos_jpeg.c \ + exynos_param.c \ + exynos_utils.c \ + exynos_v4l2.c \ + exynos_v4l2_output.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + hardware/samsung/exynos4/hal/include + +LOCAL_SHARED_LIBRARIES := libutils libcutils liblog libcamera_client libhardware +LOCAL_PRELINK_MODULE := false + +ifeq ($(TARGET_SOC),exynos4x12) + LOCAL_SHARED_LIBRARIES += libhwjpeg + LOCAL_CFLAGS += -DEXYNOS_JPEG_HW + + LOCAL_SRC_FILES += exynos_ion.c + LOCAL_CFLAGS += -DEXYNOS_ION +endif + +LOCAL_MODULE := camera.$(TARGET_BOOTLOADER_BOARD_NAME) +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/camera/MODULE_LICENSE_GPL b/camera/MODULE_LICENSE_GPL new file mode 100644 index 0000000..e69de29 diff --git a/camera/NOTICE b/camera/NOTICE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/camera/NOTICE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/camera/exynos_camera.c b/camera/exynos_camera.c new file mode 100755 index 0000000..c37bcae --- /dev/null +++ b/camera/exynos_camera.c @@ -0,0 +1,4033 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * Modified for N5110: Scott Brissenden + * + * Based on crespo libcamera and exynos4 hal libcamera: + * Copyright 2008, The Android Open Source Project + * Copyright 2010, Samsung Electronics Co. LTD + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define LOG_TAG "exynos_camera" +#include +#include + +#include "exynos_camera.h" + +#define BIG2LITTLE_ENDIAN(big) ((big & 0xff) << 24 | (big & 0xff00) << 8 | (big & 0xff0000) >> 8 | (big & 0xff000000) >> 24) + +/* + * Devices configurations + */ + + +struct exynos_camera_preset exynos_camera_presets_smdk4x12[] = { + { + .name = "ISX012", + .facing = CAMERA_FACING_BACK, + .orientation = 90, + .rotation = 0, + .hflip = 0, + .vflip = 0, + .capture_format = V4L2_PIX_FMT_NV21, + .picture_format = V4L2_PIX_FMT_YUYV, + .fimc_is = 0, + .focal_length = 3.43f, + .horizontal_view_angle = 59.6f, + .vertical_view_angle = 46.3f, + .metering = METERING_CENTER, + .params = { + .preview_size_values = "1024x768", + .preview_size = "1024x768", + .preview_format_values = "yuv420sp,yuv420p", + .preview_format = "yuv420sp", + .preview_frame_rate_values = "30,20,15", + .preview_frame_rate = 30, + .preview_fps_range_values = "(10000,30000)", + .preview_fps_range = "10000,30000", + + .picture_size_values = "2560x1920,2048x1536,1600x1200,960x720,640x480", + .picture_size = "2560x1920", + .picture_format_values = "jpeg", + .picture_format = "yuyv", + .jpeg_thumbnail_size_values = "160x120,0x0", + .jpeg_thumbnail_width = 160, + .jpeg_thumbnail_height = 120, + .jpeg_thumbnail_quality = 100, + .jpeg_quality = 90, + + .video_snapshot_supported = 0, + .full_video_snap_supported = 0, + + .recording_size = "1280x720", + .recording_size_values = "1280x720,1920x1080,720x480,640x480,352x288,320x240,176x144", + .recording_format = "yuv420sp", + + .focus_mode = "auto", + .focus_mode_values = "auto,macro,fixed", + .focus_distances = "0.15,1.20,Infinity", + .focus_areas = NULL, + .max_num_focus_areas = 1, + + .zoom_supported = 0, + //.smooth_zoom_supported = 0, + //.zoom_ratios = "100,102,104,109,111,113,119,121,124,131,134,138,146,150,155,159,165,170,182,189,200,213,222,232,243,255,283,300,319,364,400", + //.zoom = 0, + //.max_zoom = 30, + + .flash_mode = NULL, + .flash_mode_values = NULL, + + .exposure_compensation = 0, + .exposure_compensation_step = 0.5, + .min_exposure_compensation = -4, + .max_exposure_compensation = 4, + + .whitebalance = "auto", + .whitebalance_values = "auto,fluorescent,daylight,cloudy-daylight", + + .antibanding = "50hz", + .antibanding_values = "50hz,off", + + .scene_mode = "auto", + .scene_mode_values = "auto,portrait,landscape,night,beach,snow,sunset,fireworks,sports,party,candlelight,dusk-dawn,fall-color,text,back-light", + + .effect = "none", + .effect_values = "none,mono,negative,sepia,solarize,sketch,pastel", + + .iso = "auto", + .iso_values = "auto,ISO100,ISO200,ISO400,ISO800", + }, + .mbus_resolutions = NULL, + .mbus_resolutions_count = 0, + }, + { + .name = "SR130PC20", + .facing = CAMERA_FACING_FRONT, + .orientation = 270, + .rotation = 0, + .hflip = 0, + .vflip = 0, + .capture_format = V4L2_PIX_FMT_NV21, + .picture_format = V4L2_PIX_FMT_YUYV, + .fimc_is = 1, + .focal_length = 2.17f, + .horizontal_view_angle = 54.7f, + .vertical_view_angle = 52.58f, + .metering = METERING_CENTER, + .params = { + .preview_size_values = "640x480,352x288,320x240", + .preview_size = "640x480", + .preview_format_values = "yuv420sp,yuv420p", + .preview_format = "yuv420sp", + .preview_frame_rate_values = "30,20,15,8", + .preview_frame_rate = 30, + .preview_fps_range_values = "(15000,30000)", + .preview_fps_range = "15000,30000", + + .picture_size_values = "1280x960,640x480", + .picture_size = "1280x960", + .picture_format_values = "jpeg", + .picture_format = "yuyv", + .jpeg_thumbnail_size_values = "160x120,160x160,160x90,144x96", + .jpeg_thumbnail_width = 160, + .jpeg_thumbnail_height = 120, + .jpeg_thumbnail_quality = 100, + .jpeg_quality = 100, + + .video_snapshot_supported = 0, + .full_video_snap_supported = 0, + + .recording_size = "640x480", + .recording_size_values = "640x480", + .recording_format = "yuv420sp", + + .focus_mode = "fixed", + .focus_mode_values = "infinity,fixed", + .focus_distances = "0.20,0.25,Infinity", + .focus_areas = NULL, + .max_num_focus_areas = 0, + + .zoom_supported = 0, + + .flash_mode = NULL, + .flash_mode_values = NULL, + + .exposure_compensation = 0, + .exposure_compensation_step = 0.5, + .min_exposure_compensation = -4, + .max_exposure_compensation = 4, + + .whitebalance = "auto", + .whitebalance_values = "auto,fluorescent,daylight,cloudy-daylight", + + .antibanding = "50hz", + .antibanding_values = "50hz,off", + + .scene_mode = "auto", + .scene_mode_values = "auto,portrait,landscape,night,beach,snow,sunset,fireworks,sports,party,candlelight,dusk-dawn,fall-color,text,back-light", + + .effect = "none", + .effect_values = "none,mono,negative,sepia,solarize,sketch,pastel", + + .iso = "auto", + .iso_values = "auto,ISO100,ISO200,ISO400,ISO800", + }, + .mbus_resolutions = NULL, + .mbus_resolutions_count = 0, + }, +}; + +struct exynos_v4l2_node exynos_v4l2_nodes_smdk4x12[] = { + { // FIMC0 is used for capture + .id = 0, + .node = "/dev/video0", + }, + { // FIMC1 is used for preview output + .id = 1, + .node = "/dev/video1", + }, + { // FIMC2 is used for picture output + .id = 2, + .node = "/dev/video2", + }, + { // FIMC3 is used for recording output + .id = 3, + .node = "/dev/video3", + }, +}; + +struct exynox_camera_config exynos_camera_config_smdk4x12 = { + .presets = (struct exynos_camera_preset *) &exynos_camera_presets_smdk4x12, + .presets_count = 2, + .v4l2_nodes = (struct exynos_v4l2_node *) &exynos_v4l2_nodes_smdk4x12, + .v4l2_nodes_count = 4, +}; + +/* + * Exynos Camera + */ + +struct exynox_camera_config *exynos_camera_config = + &exynos_camera_config_smdk4x12; + +int exynos_camera_start(struct exynos_camera *exynos_camera, int id) +{ + int rc; + + if (exynos_camera == NULL || id >= exynos_camera->config->presets_count) + return -EINVAL; + + // ION + +#ifdef EXYNOS_ION + rc = exynos_ion_init(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to init ION", __func__); + goto error; + } + + rc = exynos_ion_open(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to open ION", __func__); + goto error; + } +#endif + // V4L2 + + rc = exynos_v4l2_init(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to init v4l2", __func__); + goto error; + } + // FIMC0 + + rc = exynos_v4l2_open(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s: Unable to open v4l2 device", __func__); + goto error; + } + + rc = exynos_v4l2_querycap_cap(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s: Unable to query capabilities", __func__); + goto error; + } + + rc = exynos_v4l2_enum_input(exynos_camera, 0, id); + if (rc < 0) { + ALOGE("%s: Unable to enumerate input", __func__); + goto error; + } + + rc = exynos_v4l2_s_input(exynos_camera, 0, id); + if (rc < 0) { + ALOGE("%s: Unable to set inputs", __func__); + goto error; + } + + // Recording + + exynos_camera->recording_metadata = 1; + + // Params + + rc = exynos_camera_params_init(exynos_camera, id); + if (rc < 0) { + ALOGE("%s: Unable to init params", __func__); + goto error; + } + + // Gralloc + + rc = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const struct hw_module_t **) &exynos_camera->gralloc); + if (rc) + ALOGE("%s: Unable to get gralloc module", __func__); + + rc = 0; + goto complete; + +error: + exynos_v4l2_close(exynos_camera, 0); + +#ifdef EXYNOS_ION + exynos_ion_close(exynos_camera); +#endif + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_stop(struct exynos_camera *exynos_camera) +{ + int i; + int id; + + if (exynos_camera == NULL || exynos_camera->config == NULL) + return; + + exynos_v4l2_close(exynos_camera, 0); + +#ifdef EXYNOS_ION + exynos_ion_close(exynos_camera); +#endif +} + +// Params + +int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id) +{ + int rc; + + if (exynos_camera == NULL || id >= exynos_camera->config->presets_count) + return -EINVAL; + + // Camera params + + exynos_camera->camera_rotation = exynos_camera->config->presets[id].rotation; + exynos_camera->camera_hflip = exynos_camera->config->presets[id].hflip; + exynos_camera->camera_vflip = exynos_camera->config->presets[id].vflip; + exynos_camera->camera_capture_format = exynos_camera->config->presets[id].capture_format; + exynos_camera->camera_picture_format = exynos_camera->config->presets[id].picture_format; + exynos_camera->camera_fimc_is = exynos_camera->config->presets[id].fimc_is; + exynos_camera->camera_focal_length = (int) (exynos_camera->config->presets[id].focal_length * 100); + exynos_camera->camera_metering = exynos_camera->config->presets[id].metering; + + exynos_camera->camera_mbus_resolutions = exynos_camera->config->presets[id].mbus_resolutions; + exynos_camera->camera_mbus_resolutions_count = exynos_camera->config->presets[id].mbus_resolutions_count; + + // Recording preview + + exynos_param_string_set(exynos_camera, "preferred-preview-size-for-video", + exynos_camera->config->presets[id].params.preview_size); + + // Preview + + exynos_param_string_set(exynos_camera, "preview-size-values", + exynos_camera->config->presets[id].params.preview_size_values); + exynos_param_string_set(exynos_camera, "preview-size", + exynos_camera->config->presets[id].params.preview_size); + exynos_param_string_set(exynos_camera, "preview-format-values", + exynos_camera->config->presets[id].params.preview_format_values); + exynos_param_string_set(exynos_camera, "preview-format", + exynos_camera->config->presets[id].params.preview_format); + exynos_param_string_set(exynos_camera, "preview-frame-rate-values", + exynos_camera->config->presets[id].params.preview_frame_rate_values); + exynos_param_int_set(exynos_camera, "preview-frame-rate", + exynos_camera->config->presets[id].params.preview_frame_rate); + exynos_param_string_set(exynos_camera, "preview-fps-range-values", + exynos_camera->config->presets[id].params.preview_fps_range_values); + exynos_param_string_set(exynos_camera, "preview-fps-range", + exynos_camera->config->presets[id].params.preview_fps_range); + + // Picture + + exynos_param_string_set(exynos_camera, "picture-size-values", + exynos_camera->config->presets[id].params.picture_size_values); + exynos_param_string_set(exynos_camera, "picture-size", + exynos_camera->config->presets[id].params.picture_size); + exynos_param_string_set(exynos_camera, "picture-format-values", + exynos_camera->config->presets[id].params.picture_format_values); + exynos_param_string_set(exynos_camera, "picture-format", + exynos_camera->config->presets[id].params.picture_format); + exynos_param_string_set(exynos_camera, "jpeg-thumbnail-size-values", + exynos_camera->config->presets[id].params.jpeg_thumbnail_size_values); + exynos_param_int_set(exynos_camera, "jpeg-thumbnail-width", + exynos_camera->config->presets[id].params.jpeg_thumbnail_width); + exynos_param_int_set(exynos_camera, "jpeg-thumbnail-height", + exynos_camera->config->presets[id].params.jpeg_thumbnail_height); + exynos_param_int_set(exynos_camera, "jpeg-thumbnail-quality", + exynos_camera->config->presets[id].params.jpeg_thumbnail_quality); + exynos_param_int_set(exynos_camera, "jpeg-quality", + exynos_camera->config->presets[id].params.jpeg_quality); + + if (exynos_camera->config->presets[id].params.video_snapshot_supported == 1) + exynos_param_string_set(exynos_camera, "video-snapshot-supported", "true"); + if (exynos_camera->config->presets[id].params.full_video_snap_supported == 1) + exynos_param_string_set(exynos_camera, "full-video-snap-supported", "true"); + + // Recording + + exynos_param_string_set(exynos_camera, "video-size", + exynos_camera->config->presets[id].params.recording_size); + exynos_param_string_set(exynos_camera, "video-size-values", + exynos_camera->config->presets[id].params.recording_size_values); + exynos_param_string_set(exynos_camera, "video-frame-format", + exynos_camera->config->presets[id].params.recording_format); + + // Focus + + exynos_param_string_set(exynos_camera, "focus-mode", + exynos_camera->config->presets[id].params.focus_mode); + exynos_param_string_set(exynos_camera, "focus-mode-values", + exynos_camera->config->presets[id].params.focus_mode_values); + exynos_param_string_set(exynos_camera, "focus-distances", + exynos_camera->config->presets[id].params.focus_distances); + if (exynos_camera->config->presets[id].params.max_num_focus_areas > 0) { + exynos_param_string_set(exynos_camera, "focus-areas", + exynos_camera->config->presets[id].params.focus_areas); + exynos_param_int_set(exynos_camera, "max-num-focus-areas", + exynos_camera->config->presets[id].params.max_num_focus_areas); + } + + // Zoom + + if (exynos_camera->config->presets[id].params.zoom_supported == 1) { + exynos_param_string_set(exynos_camera, "zoom-supported", "true"); + + if (exynos_camera->config->presets[id].params.smooth_zoom_supported == 1) + exynos_param_string_set(exynos_camera, "smooth-zoom-supported", "true"); + + if (exynos_camera->config->presets[id].params.zoom_ratios != NULL) + exynos_param_string_set(exynos_camera, "zoom-ratios", exynos_camera->config->presets[id].params.zoom_ratios); + + exynos_param_int_set(exynos_camera, "zoom", exynos_camera->config->presets[id].params.zoom); + exynos_param_int_set(exynos_camera, "max-zoom", exynos_camera->config->presets[id].params.max_zoom); + + } else { + exynos_param_string_set(exynos_camera, "zoom-supported", "false"); + } + + // Flash + + exynos_param_string_set(exynos_camera, "flash-mode", + exynos_camera->config->presets[id].params.flash_mode); + exynos_param_string_set(exynos_camera, "flash-mode-values", + exynos_camera->config->presets[id].params.flash_mode_values); + + // Exposure + + exynos_param_int_set(exynos_camera, "exposure-compensation", + exynos_camera->config->presets[id].params.exposure_compensation); + exynos_param_float_set(exynos_camera, "exposure-compensation-step", + exynos_camera->config->presets[id].params.exposure_compensation_step); + exynos_param_int_set(exynos_camera, "min-exposure-compensation", + exynos_camera->config->presets[id].params.min_exposure_compensation); + exynos_param_int_set(exynos_camera, "max-exposure-compensation", + exynos_camera->config->presets[id].params.max_exposure_compensation); + + // Antibanding + + exynos_param_string_set(exynos_camera, "antibanding", + exynos_camera->config->presets[id].params.antibanding); + exynos_param_string_set(exynos_camera, "antibanding-values", + exynos_camera->config->presets[id].params.antibanding_values); + + // WB + + exynos_param_string_set(exynos_camera, "whitebalance", + exynos_camera->config->presets[id].params.whitebalance); + exynos_param_string_set(exynos_camera, "whitebalance-values", + exynos_camera->config->presets[id].params.whitebalance_values); + + // Scene mode + + exynos_param_string_set(exynos_camera, "scene-mode", + exynos_camera->config->presets[id].params.scene_mode); + exynos_param_string_set(exynos_camera, "scene-mode-values", + exynos_camera->config->presets[id].params.scene_mode_values); + + // Effect + + exynos_param_string_set(exynos_camera, "effect", + exynos_camera->config->presets[id].params.effect); + exynos_param_string_set(exynos_camera, "effect-values", + exynos_camera->config->presets[id].params.effect_values); + + // ISO + + exynos_param_string_set(exynos_camera, "iso", + exynos_camera->config->presets[id].params.iso); + exynos_param_string_set(exynos_camera, "iso-values", + exynos_camera->config->presets[id].params.iso_values); + + // Camera + + exynos_param_float_set(exynos_camera, "focal-length", + exynos_camera->config->presets[id].focal_length); + exynos_param_float_set(exynos_camera, "horizontal-view-angle", + exynos_camera->config->presets[id].horizontal_view_angle); + exynos_param_float_set(exynos_camera, "vertical-view-angle", + exynos_camera->config->presets[id].vertical_view_angle); + + rc = exynos_camera_params_apply(exynos_camera, 1); + if (rc < 0) { + ALOGE("%s: Unable to apply params", __func__); + return -1; + } + + return 0; +} + +int exynos_camera_params_apply(struct exynos_camera *exynos_camera, int force) +{ + char *recording_hint_string; + char *recording_preview_size_string; + + char *preview_size_string; + int preview_width = 0; + int preview_height = 0; + char *preview_format_string; + int preview_format; + int preview_fps; + + char *picture_size_string; + int picture_width = 0; + int picture_height = 0; + char *picture_format_string; + int picture_format; + + int jpeg_thumbnail_width; + int jpeg_thumbnail_height; + int jpeg_thumbnail_quality; + int jpeg_quality; + + char *video_size_string; + int recording_width = 0; + int recording_height = 0; + char *video_frame_format_string; + int recording_format; + int camera_sensor_mode; + int fimc_is_mode = 0; + + char *focus_mode_string; + int focus_mode = 0; + char *focus_areas_string; + int focus_left, focus_top, focus_right, focus_bottom, focus_weigth; + int focus_x; + int focus_y; + + char *zoom_supported_string; + int zoom, max_zoom; + + char *flash_mode_string; + int flash_mode; + + int exposure_compensation; + int min_exposure_compensation; + int max_exposure_compensation; + + char *antibanding_string; + int antibanding; + + char *whitebalance_string; + int whitebalance; + + char *scene_mode_string; + int scene_mode; + + char *effect_string; + int effect; + + char *iso_string; + int iso; + + int w, h; + char *k; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + // Preview + + preview_size_string = exynos_param_string_get(exynos_camera, "preview-size"); + if (preview_size_string != NULL) { + sscanf(preview_size_string, "%dx%d", &preview_width, &preview_height); + + if (preview_width != 0 && preview_width != exynos_camera->preview_width) + exynos_camera->preview_width = preview_width; + if (preview_height != 0 && preview_height != exynos_camera->preview_height) + exynos_camera->preview_height = preview_height; + } + + preview_format_string = exynos_param_string_get(exynos_camera, "preview-format"); + if (preview_format_string != NULL) { + if (strcmp(preview_format_string, "yuv420sp") == 0) { + preview_format = V4L2_PIX_FMT_NV21; + } else if (strcmp(preview_format_string, "yuv420p") == 0) { + preview_format = V4L2_PIX_FMT_YUV420; + } else if (strcmp(preview_format_string, "rgb565") == 0) { + preview_format = V4L2_PIX_FMT_RGB565; + } else if (strcmp(preview_format_string, "rgb8888") == 0) { + preview_format = V4L2_PIX_FMT_RGB32; + } else { + ALOGE("%s: Unsupported preview format: %s", __func__, preview_format_string); + preview_format = V4L2_PIX_FMT_NV21; + } + + if (preview_format != exynos_camera->preview_format) + exynos_camera->preview_format = preview_format; + } + + preview_fps = exynos_param_int_get(exynos_camera, "preview-frame-rate"); + if (preview_fps > 0) + exynos_camera->preview_fps = preview_fps; + else + exynos_camera->preview_fps = 0; + + // Picture + + picture_size_string = exynos_param_string_get(exynos_camera, "picture-size"); + if (picture_size_string != NULL) { + sscanf(picture_size_string, "%dx%d", &picture_width, &picture_height); + + if (picture_width != 0 && picture_height != 0 && (picture_width != exynos_camera->picture_width || picture_height != exynos_camera->picture_height)) { + exynos_camera->picture_width = picture_width; + exynos_camera->picture_height = picture_height; + } + } + + picture_format_string = exynos_param_string_get(exynos_camera, "picture-format"); + if (picture_format_string != NULL) { + if (strcmp(picture_format_string, "jpeg") == 0) { + picture_format = V4L2_PIX_FMT_JPEG; + }else if (strcmp(picture_format_string, "yuyv") == 0) { + picture_format = V4L2_PIX_FMT_YUYV; + } else { + ALOGE("%s: Unsupported picture format: %s", __func__, picture_format_string); + picture_format = V4L2_PIX_FMT_JPEG; + } + + if (picture_format != exynos_camera->picture_format) + exynos_camera->picture_format = picture_format; + } + + jpeg_thumbnail_width = exynos_param_int_get(exynos_camera, "jpeg-thumbnail-width"); + if (jpeg_thumbnail_width > 0) + exynos_camera->jpeg_thumbnail_width = jpeg_thumbnail_width; + + jpeg_thumbnail_height = exynos_param_int_get(exynos_camera, "jpeg-thumbnail-height"); + if (jpeg_thumbnail_height > 0) + exynos_camera->jpeg_thumbnail_height = jpeg_thumbnail_height; + + jpeg_thumbnail_quality = exynos_param_int_get(exynos_camera, "jpeg-thumbnail-quality"); + if (jpeg_thumbnail_quality > 0) + exynos_camera->jpeg_thumbnail_quality = jpeg_thumbnail_quality; + + jpeg_quality = exynos_param_int_get(exynos_camera, "jpeg-quality"); + if (jpeg_quality <= 100 && jpeg_quality >= 0 && (jpeg_quality != exynos_camera->jpeg_quality || force)) { + exynos_camera->jpeg_quality = jpeg_quality; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_QUALITY, jpeg_quality); + if (rc < 0) + ALOGE("%s: Unable to set jpeg quality", __func__); + } + + // Recording + + video_size_string = exynos_param_string_get(exynos_camera, "video-size"); + if (video_size_string == NULL) + video_size_string = exynos_param_string_get(exynos_camera, "preview-size"); + + if (video_size_string != NULL) { + sscanf(video_size_string, "%dx%d", &recording_width, &recording_height); + + if (recording_width != 0 && recording_width != exynos_camera->recording_width) + exynos_camera->recording_width = recording_width; + if (recording_height != 0 && recording_height != exynos_camera->recording_height) + exynos_camera->recording_height = recording_height; + } + + video_frame_format_string = exynos_param_string_get(exynos_camera, "video-frame-format"); + if (video_frame_format_string != NULL) { + if (strcmp(video_frame_format_string, "yuv420sp") == 0) { + recording_format = V4L2_PIX_FMT_NV12; + } else if (strcmp(video_frame_format_string, "yuv420p") == 0) { + recording_format = V4L2_PIX_FMT_YUV420; + } else if (strcmp(video_frame_format_string, "rgb565") == 0) { + recording_format = V4L2_PIX_FMT_RGB565; + } else if (strcmp(video_frame_format_string, "rgb8888") == 0) { + recording_format = V4L2_PIX_FMT_RGB32; + } else { + ALOGE("%s: Unsupported recording format: %s", __func__, video_frame_format_string); + recording_format = V4L2_PIX_FMT_NV12; + } + + if (recording_format != exynos_camera->recording_format) + exynos_camera->recording_format = recording_format; + } + + recording_hint_string = exynos_param_string_get(exynos_camera, "recording-hint"); + if (recording_hint_string != NULL && strcmp(recording_hint_string, "true") == 0) { + camera_sensor_mode = SENSOR_MOVIE; + + k = exynos_param_string_get(exynos_camera, "preview-size-values"); + while (recording_width != 0 && recording_height != 0) { + if (k == NULL) + break; + + sscanf(k, "%dx%d", &w, &h); + + // Look for same aspect ratio + if ((recording_width * h) / recording_height == w) { + preview_width = w; + preview_height = h; + break; + } + + k = strchr(k, ','); + if (k == NULL) + break; + + k++; + } + + if (preview_width != 0 && preview_width != exynos_camera->preview_width) + exynos_camera->preview_width = preview_width; + if (preview_height != 0 && preview_height != exynos_camera->preview_height) + exynos_camera->preview_height = preview_height; + } else { + camera_sensor_mode = SENSOR_CAMERA; + } + + // Switching modes + + if (camera_sensor_mode != exynos_camera->camera_sensor_mode) { + exynos_camera->camera_sensor_mode = camera_sensor_mode; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SENSOR_MODE, camera_sensor_mode); + if (rc < 0) + ALOGE("%s: Unable to set sensor mode", __func__); + } + + // Focus + + focus_areas_string = exynos_param_string_get(exynos_camera, "focus-areas"); + if (focus_areas_string != NULL) { + focus_left = focus_top = focus_right = focus_bottom = focus_weigth = 0; + + rc = sscanf(focus_areas_string, "(%d,%d,%d,%d,%d)", + &focus_left, &focus_top, &focus_right, &focus_bottom, &focus_weigth); + if (rc != 5) { + ALOGE("%s: Unable to scan focus areas", __func__); + } else if (focus_left != 0 && focus_top != 0 && focus_right != 0 && focus_bottom != 0) { + focus_x = (((focus_left + focus_right) / 2) + 1000) * preview_width / 2000; + focus_y = (((focus_top + focus_bottom) / 2) + 1000) * preview_height / 2000; + + if (focus_x != exynos_camera->focus_x || force) { + exynos_camera->focus_x = focus_x; + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_OBJECT_POSITION_X, focus_x); + if (rc < 0) + ALOGE("%s: Unable to set object x position", __func__); + } + + if (focus_y != exynos_camera->focus_y || force) { + exynos_camera->focus_y = focus_y; + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_OBJECT_POSITION_Y, focus_y); + if (rc < 0) + ALOGE("%s: Unable to set object y position", __func__); + } + + focus_mode = FOCUS_MODE_TOUCH; + } + } + + focus_mode_string = exynos_param_string_get(exynos_camera, "focus-mode"); + if (focus_mode_string != NULL) { + if (focus_mode == 0) { + if (strcmp(focus_mode_string, "auto") == 0) + focus_mode = FOCUS_MODE_AUTO; + else if (strcmp(focus_mode_string, "infinity") == 0) + focus_mode = FOCUS_MODE_INFINITY; + else if (strcmp(focus_mode_string, "macro") == 0) + focus_mode = FOCUS_MODE_MACRO; + else if (strcmp(focus_mode_string, "fixed") == 0) + focus_mode = FOCUS_MODE_FIXED; + else if (strcmp(focus_mode_string, "facedetect") == 0) + focus_mode = FOCUS_MODE_FACEDETECT; + else if (strcmp(focus_mode_string, "continuous-video") == 0) + focus_mode = FOCUS_MODE_CONTINOUS_VIDEO; + else if (strcmp(focus_mode_string, "continuous-picture") == 0) + focus_mode = FOCUS_MODE_CONTINOUS_PICTURE; + else + focus_mode = FOCUS_MODE_AUTO; + } + + if (focus_mode != exynos_camera->focus_mode || force) { + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_FOCUS_MODE, focus_mode); + if (rc < 0) + ALOGE("%s: Unable to set focus mode", __func__); + } + + exynos_camera->focus_mode = focus_mode; + } + + // Zoom + + zoom_supported_string = exynos_param_string_get(exynos_camera, "zoom-supported"); + if (zoom_supported_string != NULL && strcmp(zoom_supported_string, "true") == 0) { + zoom = exynos_param_int_get(exynos_camera, "zoom"); + max_zoom = exynos_param_int_get(exynos_camera, "max-zoom"); + if (zoom <= max_zoom && zoom >= 0 && (zoom != exynos_camera->zoom || force)) { + exynos_camera->zoom = zoom; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ZOOM, zoom); + if (rc < 0) + ALOGE("%s: Unable to set camera zoom", __func__); + } + + } + + // Flash + + flash_mode_string = exynos_param_string_get(exynos_camera, "flash-mode"); + if (flash_mode_string != NULL) { + if (strcmp(flash_mode_string, "off") == 0) + flash_mode = FLASH_MODE_OFF; + else if (strcmp(flash_mode_string, "auto") == 0) + flash_mode = FLASH_MODE_AUTO; + else if (strcmp(flash_mode_string, "on") == 0) + flash_mode = FLASH_MODE_ON; + else if (strcmp(flash_mode_string, "torch") == 0) + flash_mode = FLASH_MODE_TORCH; + else + flash_mode = FLASH_MODE_AUTO; + + if (flash_mode != exynos_camera->flash_mode || force) { + exynos_camera->flash_mode = flash_mode; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_FLASH_MODE, flash_mode); + if (rc < 0) + ALOGE("%s:Unable to set flash mode", __func__); + } + } + + // Exposure + + exposure_compensation = exynos_param_int_get(exynos_camera, "exposure-compensation"); + min_exposure_compensation = exynos_param_int_get(exynos_camera, "min-exposure-compensation"); + max_exposure_compensation = exynos_param_int_get(exynos_camera, "max-exposure-compensation"); + + if (exposure_compensation <= max_exposure_compensation && exposure_compensation >= min_exposure_compensation && + (exposure_compensation != exynos_camera->exposure_compensation || force)) { + exynos_camera->exposure_compensation = exposure_compensation; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_BRIGHTNESS, exposure_compensation); + if (rc < 0) + ALOGE("%s: Unable to set exposure", __func__); + } + + // Antibanding + + antibanding_string = exynos_param_string_get(exynos_camera, "antibanding"); + if (antibanding_string != NULL) { + if (strcmp(antibanding_string, "auto") == 0) + antibanding = ANTI_BANDING_AUTO; + else if (strcmp(antibanding_string, "50hz") == 0) + antibanding = ANTI_BANDING_50HZ; + else if (strcmp(antibanding_string, "off") == 0) + antibanding = ANTI_BANDING_OFF; + else + antibanding = ANTI_BANDING_AUTO; + + if (antibanding != exynos_camera->antibanding || force) { + exynos_camera->antibanding = antibanding; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ANTI_BANDING, antibanding); + if (rc < 0) + ALOGE("%s: Unable to set antibanding", __func__); + } + } + + if(!exynos_camera->camera_fimc_is){ + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_AE_LOCK_UNLOCK, AE_UNLOCK); + if (rc < 0) + ALOGE("%s: Unable to set antibanding", __func__); + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_AWB_LOCK_UNLOCK, AWB_UNLOCK); + if (rc < 0) + ALOGE("%s: Unable to set antibanding", __func__); + } + + // WB + + whitebalance_string = exynos_param_string_get(exynos_camera, "whitebalance"); + if (whitebalance_string != NULL) { + if (strcmp(whitebalance_string, "auto") == 0) + whitebalance = WHITE_BALANCE_AUTO; + else if (strcmp(whitebalance_string, "incandescent") == 0) + whitebalance = WHITE_BALANCE_TUNGSTEN; + else if (strcmp(whitebalance_string, "fluorescent") == 0) + whitebalance = WHITE_BALANCE_FLUORESCENT; + else if (strcmp(whitebalance_string, "daylight") == 0) + whitebalance = WHITE_BALANCE_SUNNY; + else if (strcmp(whitebalance_string, "cloudy-daylight") == 0) + whitebalance = WHITE_BALANCE_CLOUDY; + else + whitebalance = WHITE_BALANCE_AUTO; + + if (whitebalance != exynos_camera->whitebalance || force) { + exynos_camera->whitebalance = whitebalance; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_WHITE_BALANCE, whitebalance); + if (rc < 0) + ALOGE("%s: Unable to set whitebalance", __func__); + } + } + + // Scene mode + + scene_mode_string = exynos_param_string_get(exynos_camera, "scene-mode"); + if (scene_mode_string != NULL) { + if (strcmp(scene_mode_string, "auto") == 0) + scene_mode = SCENE_MODE_NONE; + else if (strcmp(scene_mode_string, "portrait") == 0) + scene_mode = SCENE_MODE_PORTRAIT; + else if (strcmp(scene_mode_string, "landscape") == 0) + scene_mode = SCENE_MODE_LANDSCAPE; + else if (strcmp(scene_mode_string, "night") == 0) + scene_mode = SCENE_MODE_NIGHTSHOT; + else if (strcmp(scene_mode_string, "beach") == 0) + scene_mode = SCENE_MODE_BEACH_SNOW; + else if (strcmp(scene_mode_string, "snow") == 0) + scene_mode = SCENE_MODE_BEACH_SNOW; + else if (strcmp(scene_mode_string, "sunset") == 0) + scene_mode = SCENE_MODE_SUNSET; + else if (strcmp(scene_mode_string, "fireworks") == 0) + scene_mode = SCENE_MODE_FIREWORKS; + else if (strcmp(scene_mode_string, "sports") == 0) + scene_mode = SCENE_MODE_SPORTS; + else if (strcmp(scene_mode_string, "party") == 0) + scene_mode = SCENE_MODE_PARTY_INDOOR; + else if (strcmp(scene_mode_string, "candlelight") == 0) + scene_mode = SCENE_MODE_CANDLE_LIGHT; + else if (strcmp(scene_mode_string, "dusk-dawn") == 0) + scene_mode = SCENE_MODE_DUSK_DAWN; + else if (strcmp(scene_mode_string, "fall-color") == 0) + scene_mode = SCENE_MODE_FALL_COLOR; + else if (strcmp(scene_mode_string, "back-light") == 0) + scene_mode = SCENE_MODE_BACK_LIGHT; + else if (strcmp(scene_mode_string, "text") == 0) + scene_mode = SCENE_MODE_TEXT; + else + scene_mode = SCENE_MODE_NONE; + + if (scene_mode != exynos_camera->scene_mode || force) { + exynos_camera->scene_mode = scene_mode; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SCENE_MODE, scene_mode); + if (rc < 0) + ALOGE("%s: Unable to set scene mode", __func__); + } + } + + // Effect + + effect_string = exynos_param_string_get(exynos_camera, "effect"); + if (effect_string != NULL) { + if (strcmp(effect_string, "auto") == 0) + effect = IMAGE_EFFECT_NONE; + if (strcmp(effect_string, "none") == 0) + effect = IMAGE_EFFECT_NONE; + else if (strcmp(effect_string, "mono") == 0) + effect = IMAGE_EFFECT_BNW; + else if (strcmp(effect_string, "negative") == 0) + effect = IMAGE_EFFECT_NEGATIVE; + else if (strcmp(effect_string, "sepia") == 0) + effect = IMAGE_EFFECT_SEPIA; + else if (strcmp(effect_string, "aqua") == 0) + effect = IMAGE_EFFECT_AQUA; + else if (strcmp(effect_string, "solarize") == 0) + effect = IMAGE_EFFECT_SOLARIZE; + else if (strcmp(effect_string, "posterize") == 0) + effect = IMAGE_EFFECT_POSTERIZE; + else if (strcmp(effect_string, "washed") == 0) + effect = IMAGE_EFFECT_WASHED; + else if (strcmp(effect_string, "sketch") == 0) + effect = IMAGE_EFFECT_SKETCH; + else if (strcmp(effect_string, "vintage-warm") == 0) + effect = IMAGE_EFFECT_VINTAGE_WARM; + else if (strcmp(effect_string, "vintage-cold") == 0) + effect = IMAGE_EFFECT_VINTAGE_COLD; + else if (strcmp(effect_string, "point-blue") == 0) + effect = IMAGE_EFFECT_POINT_BLUE; + else if (strcmp(effect_string, "point-red-yellow") == 0) + effect = IMAGE_EFFECT_POINT_RED_YELLOW; + else if (strcmp(effect_string, "point-green") == 0) + effect = IMAGE_EFFECT_POINT_GREEN; + else + effect = IMAGE_EFFECT_NONE; + + if (effect != exynos_camera->effect || force) { + exynos_camera->effect = effect; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EFFECT, effect); + if (rc < 0) + ALOGE("%s: Unable to set effect", __func__); + } + } + + // ISO + + iso_string = exynos_param_string_get(exynos_camera, "iso"); + if (iso_string != NULL) { + if (strcmp(iso_string, "auto") == 0) + iso = ISO_AUTO; + else if (strcmp(iso_string, "ISO50") == 0) + iso = ISO_50; + else if (strcmp(iso_string, "ISO100") == 0) + iso = ISO_100; + else if (strcmp(iso_string, "ISO200") == 0) + iso = ISO_200; + else if (strcmp(iso_string, "ISO400") == 0) + iso = ISO_400; + else if (strcmp(iso_string, "ISO800") == 0) + iso = ISO_800; + else + iso = ISO_AUTO; + + if (iso != exynos_camera->iso || force) { + exynos_camera->iso = iso; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ISO, iso); + if (rc < 0) + ALOGE("%s: Unable to set iso", __func__); + } + } + + return 0; +} + +// Capture +int exynos_camera_capture(struct exynos_camera *exynos_camera) +{ + struct exynos_camera_capture_listener *listener; + struct exynos_camera_buffer *buffers = NULL; + struct exynos_camera_buffer *buffer; + struct list_head *list; + int width, height, format; + int yuv_length, jpeg_length; + int jpeg_offset, jpeg_size; + int jpeg_thumbnail_offset, jpeg_thumbnail_size; + int buffers_count; + int buffer_length; + int auto_focus_result; + int decoded; + int busy; + void *pointer; + int address; + int offset; + int index; + int rc; + int value; + + if (exynos_camera == NULL) + return -EINVAL; + + width = exynos_camera->capture_width; + height = exynos_camera->capture_height; + format = exynos_camera->capture_format; + + buffers_count = exynos_camera->capture_buffers_count; + buffer_length = exynos_camera->capture_buffer_length; + + // V4L2 + + //ALOGE("%s : ",__func__); + + index = exynos_v4l2_dqbuf_cap(exynos_camera, 0); + if (index < 0 || index >= buffers_count) { + rc = exynos_v4l2_poll(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s Unable to poll", __func__); + goto error; + } else if (rc == 0) { + // Timeout + rc = 0; + goto complete; + } + + index = exynos_v4l2_dqbuf_cap(exynos_camera, 0); + if (index < 0 || index >= buffers_count) { + ALOGE("%s: Unable to dequeue buffer", __func__); + goto error; + } + } + + exynos_camera->capture_memory_index = index; + + address = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_PADDR_Y, index); + if (address == 0 || address == (int) 0xffffffff) { + ALOGE("%s: Unable to get address", __func__); + goto error; + } + + offset = address - exynos_camera->capture_memory_address; + if (offset != index * buffer_length) + ALOGE("%s: Inconsistent memory offset (0x%x/0x%x)", __func__, offset, index * buffer_length); + + pointer = (void *) ((unsigned char *) exynos_camera->capture_memory->data + offset); + + value = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_PADDR_CBCR, 0); + + // Buffers + + switch (format) { + case V4L2_PIX_FMT_JPEG: + jpeg_size = jpeg_offset = 0; + jpeg_thumbnail_size = jpeg_thumbnail_offset = 0; + + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_MAIN_SIZE, &jpeg_size); + if (rc < 0 || jpeg_size <= 0) { + ALOGE("%s: Unable to get jpeg size", __func__); + goto error; + } + + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_MAIN_OFFSET, &jpeg_offset); + if (rc < 0) { + ALOGE("%s: Unable to get jpeg offset", __func__); + goto error; + } + + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_THUMB_SIZE, &jpeg_thumbnail_size); + if (rc < 0 || jpeg_thumbnail_size <= 0) { + ALOGE("%s: Unable to get jpeg thumbnail size", __func__); + goto error; + } + + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_THUMB_OFFSET, &jpeg_thumbnail_offset); + if (rc < 0) { + ALOGE("%s: Unable to get jpeg thumbnail offset", __func__); + goto error; + } + + buffers_count = 2; + buffers = (struct exynos_camera_buffer *) calloc(buffers_count, sizeof(struct exynos_camera_buffer)); + + buffer = buffers; + + buffer->pointer = (void *) ((unsigned char *) pointer + jpeg_offset); + buffer->address = address + jpeg_offset; + buffer->length = jpeg_size; + buffer->width = exynos_camera->picture_width; + buffer->height = exynos_camera->picture_height; + buffer->format = V4L2_PIX_FMT_JPEG; + + buffer = (struct exynos_camera_buffer *) ((unsigned char *) buffer + sizeof(struct exynos_camera_buffer)); + + buffer->pointer = (void *) ((unsigned char *) pointer + jpeg_thumbnail_offset); + buffer->address = address + jpeg_thumbnail_offset; + buffer->length = jpeg_thumbnail_size; + buffer->width = exynos_camera->jpeg_thumbnail_width; + buffer->height = exynos_camera->jpeg_thumbnail_height; + buffer->format = V4L2_PIX_FMT_JPEG; + break; + default: + buffers_count = 1; + buffers = (struct exynos_camera_buffer *) calloc(buffers_count, sizeof(struct exynos_camera_buffer)); + + buffer = buffers; + + buffer->pointer = pointer; + buffer->address = address; + buffer->length = buffer_length; + buffer->width = width; + buffer->height = height; + buffer->format = format; + break; + } + + // Listeners + + list = (struct list_head *) exynos_camera->capture_listeners; + while (list != NULL) { + listener = (struct exynos_camera_capture_listener *) list; + + if (listener->callback == NULL) + goto list_continue_callback; + + /* + * Callback must never call a capture-locked function or it will + * block. Hence, do not unregister the listener in callback. + */ + + listener->callback(exynos_camera, buffers, buffers_count); + +list_continue_callback: + list = list->next; + } + + do { + busy = 0; + + list = (struct list_head *) exynos_camera->capture_listeners; + while (list != NULL) { + listener = (struct exynos_camera_capture_listener *) list; + + if (listener->callback == NULL) + goto list_continue_busy; + + busy |= listener->busy; + +list_continue_busy: + list = list->next; + } + + if (busy) + usleep(1000); + } while (busy); + + rc = exynos_v4l2_qbuf_cap(exynos_camera, 0, index); + if (rc < 0) { + ALOGE("%s: Unable to queue buffer", __func__); + goto error; + } + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + if (buffers != NULL) + free(buffers); + + return rc; +} + +void *exynos_camera_capture_thread(void *data) +{ + struct exynos_camera *exynos_camera; + int rc; + + if (data == NULL) + return NULL; + + exynos_camera = (struct exynos_camera *) data; + + ALOGE("%s: Starting thread", __func__); + exynos_camera->capture_thread_running = 1; + + while (exynos_camera->capture_thread_enabled) { + pthread_mutex_lock(&exynos_camera->capture_lock_mutex); + + while (exynos_camera->capture_enabled) { + pthread_mutex_lock(&exynos_camera->capture_mutex); + + if (!exynos_camera->capture_enabled) { + pthread_mutex_unlock(&exynos_camera->capture_mutex); + break; + } + + rc = exynos_camera_capture(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to capture", __func__); + pthread_mutex_unlock(&exynos_camera->capture_mutex); + break; + } + + pthread_mutex_unlock(&exynos_camera->capture_mutex); + + // Wait a bit to let others lock the mutex if they need to + usleep(10); + } + } + + exynos_camera->capture_thread_running = 0; + ALOGE("%s: Exiting thread", __func__); + + return NULL; +} + +int exynos_camera_capture_thread_start(struct exynos_camera *exynos_camera) +{ + pthread_attr_t thread_attr; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->capture_thread_enabled) { + ALOGE("Capture thread was already started!"); + return -1; + } + + pthread_mutex_init(&exynos_camera->capture_mutex, NULL); + pthread_mutex_init(&exynos_camera->capture_lock_mutex, NULL); + + // Initial lock + pthread_mutex_lock(&exynos_camera->capture_lock_mutex); + + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + + exynos_camera->capture_thread_enabled = 1; + + rc = pthread_create(&exynos_camera->capture_thread, &thread_attr, exynos_camera_capture_thread, (void *) exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to create thread", __func__); + goto error; + } + + rc = 0; + goto complete; + +error: + pthread_mutex_destroy(&exynos_camera->capture_mutex); + pthread_mutex_destroy(&exynos_camera->capture_lock_mutex); + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_capture_thread_stop(struct exynos_camera *exynos_camera) +{ + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->capture_thread_enabled) { + ALOGE("Capture thread was already stopped!"); + return; + } + + exynos_camera->capture_enabled = 0; + exynos_camera->capture_thread_enabled = 0; + + pthread_mutex_unlock(&exynos_camera->capture_lock_mutex); + + // Wait for the thread to end + i = 0; + while (exynos_camera->capture_thread_running) { + if (i++ > 10000) { + ALOGE("Capture thread is taking too long to end, something is going wrong"); + break; + } + usleep(100); + } + + if (exynos_camera->capture_enabled) { + pthread_mutex_lock(&exynos_camera->capture_mutex); + exynos_camera_capture_stop(exynos_camera); + pthread_mutex_unlock(&exynos_camera->capture_mutex); + } + + pthread_mutex_destroy(&exynos_camera->capture_mutex); + pthread_mutex_destroy(&exynos_camera->capture_lock_mutex); +} + +int exynos_camera_capture_start(struct exynos_camera *exynos_camera, int is_capture) +{ + struct v4l2_streamparm fps_param; + int width, height, format; + int mbus_width, mbus_height; + int buffers_count, buffer_length; + camera_memory_t *memory = NULL; + int value; + int fd; + int rc; + int i; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->capture_enabled) { + ALOGE("Capture was already started!"); + return -1; + } + + width = exynos_camera->capture_width; + height = exynos_camera->capture_height; + format = exynos_camera->capture_format; + + // V4L2 + + rc = exynos_v4l2_enum_fmt_cap(exynos_camera, 0, format); + if (rc < 0) { + ALOGE("%s: Unable to enumerate formats", __func__); + goto error; + } + + mbus_width = width; + mbus_height = height; + + if (exynos_camera->camera_mbus_resolutions != NULL) { + for (i = 0; i < exynos_camera->camera_mbus_resolutions_count; i++) { + if (exynos_camera->camera_mbus_resolutions[i].width == width && exynos_camera->camera_mbus_resolutions[i].height == height) { + mbus_width = exynos_camera->camera_mbus_resolutions[i].mbus_width; + mbus_height = exynos_camera->camera_mbus_resolutions[i].mbus_height; + break; + } + } + } + + if(!is_capture || exynos_camera->preview_output_enabled) { + rc = exynos_v4l2_s_fmt_pix_cap(exynos_camera, 0, width, height, format, V4L2_PIX_FMT_MODE_PREVIEW); + if (rc < 0) { + ALOGE("%s: Unable to set capture pixel format", __func__); + goto error; + } + + // Set MBUS width/height/format + rc = exynos_v4l2_s_fmt_pix(exynos_camera, 0, V4L2_BUF_TYPE_PRIVATE, mbus_width, mbus_height, format, V4L2_FIELD_NONE, V4L2_PIX_FMT_MODE_PREVIEW); + if (rc < 0) { + ALOGE("%s: Unable to set MBUS capture pixel format", __func__); + goto error; + } + }else { + rc = exynos_v4l2_s_fmt_pix_cap(exynos_camera, 0, width, height, format, V4L2_PIX_FMT_MODE_CAPTURE); + if (rc < 0) { + ALOGE("%s: Unable to set capture pixel format", __func__); + goto error; + } + + // Set MBUS width/height/format + rc = exynos_v4l2_s_fmt_pix(exynos_camera, 0, V4L2_BUF_TYPE_PRIVATE, mbus_width, mbus_height, format, IS_MODE_CAPTURE_STILL, V4L2_PIX_FMT_MODE_CAPTURE); + if (rc < 0) { + ALOGE("%s: Unable to set MBUS capture pixel format", __func__); + goto error; + } + } + + if(!is_capture || exynos_camera->preview_output_enabled){ + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_EMBEDDEDDATA_ENABLE, 0); + if (rc < 0) { + ALOGE("%s: Unable to set embdedded data enable", __func__); + goto error; + } + } + + // Let's assume FIMC0 has memory available through mmap + if(!is_capture || exynos_camera->preview_output_enabled) { + for (i = EXYNOS_CAMERA_PREVIEW_BUFFERS_COUNT; i > 0; i--) { + rc = exynos_v4l2_reqbufs_cap(exynos_camera, 0, i); + if (rc >= 0) + break; + } + }else { + for (i = EXYNOS_CAMERA_CAPTURE_BUFFERS_COUNT; i > 0; i--) { + rc = exynos_v4l2_reqbufs_cap(exynos_camera, 0, i); + if (rc >= 0) + break; + } + } + + if (rc < 0) { + ALOGE("%s: Unable to request buffers", __func__); + goto error; + } + + buffers_count = rc; + ALOGD("Found %d buffers available for capture!", buffers_count); + + memset(&fps_param, 0, sizeof(fps_param)); + fps_param.parm.capture.timeperframe.numerator = 1; + fps_param.parm.capture.timeperframe.denominator = exynos_camera->preview_fps; + + rc = exynos_v4l2_s_parm_cap(exynos_camera, 0, &fps_param); + if (rc < 0) { + ALOGE("%s: Unable to set fps", __func__); + goto error; + } + + for (i = 0; i < buffers_count; i++) { + rc = exynos_v4l2_querybuf_cap(exynos_camera, 0, i); + if (rc < 0) { + ALOGE("%s: Unable to query buffers", __func__); + goto error; + } + } + + buffer_length = rc; + + value = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_PADDR_Y, 0); + if (value == 0 || value == (int) 0xffffffff) { + ALOGE("%s: Unable to get address", __func__); + goto error; + } + + exynos_camera->capture_memory_address = value; + + value = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_PADDR_CBCR, 0); + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + fd = exynos_v4l2_fd(exynos_camera, 0); + if (fd < 0) { + ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, 0); + goto error; + } + + exynos_camera->capture_memory = NULL; + + memory = exynos_camera->callbacks.request_memory(fd, buffer_length, buffers_count, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + + exynos_camera->capture_memory = memory; + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + for (i = 0; i < buffers_count; i++) { + rc = exynos_v4l2_qbuf_cap(exynos_camera, 0, i); + if (rc < 0) { + ALOGE("%s: Unable to queue buffer", __func__); + goto error; + } + } + + exynos_camera->capture_buffers_count = buffers_count; + exynos_camera->capture_buffer_length = buffer_length; + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_ROTATION, + exynos_camera->camera_rotation); + if (rc < 0) { + ALOGE("%s: Unable to set rotation", __func__); + goto error; + } + + rc = exynos_v4l2_streamon_cap(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s: Unable to start stream", __func__); + goto error; + } + + exynos_camera->capture_enabled = 1; + + if(!is_capture){ + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_CAPTURE_MODE, EXYNOS_CAMERA_UNKNOWN_CAPTURE_MODE); + if (rc < 0) { + ALOGE("%s: Unable to set V4L2_CID_CAMERA_CAPTURE_MODE", __func__); + goto error; + } + } + + pthread_mutex_unlock(&exynos_camera->capture_lock_mutex); + + rc = 0; + goto complete; + +error: + if (exynos_camera->capture_memory != NULL && exynos_camera->capture_memory->release != NULL) { + exynos_camera->capture_memory->release(exynos_camera->capture_memory); + exynos_camera->capture_memory = NULL; + } + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_capture_stop(struct exynos_camera *exynos_camera) +{ + int rc; + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->capture_enabled) { + ALOGE("Capture was already stopped!"); + return; + } + + rc = exynos_v4l2_streamoff_cap(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s: Unable to stop stream", __func__); + } + + if (exynos_camera->capture_memory != NULL && exynos_camera->capture_memory->release != NULL) { + exynos_camera->capture_memory->release(exynos_camera->capture_memory); + exynos_camera->capture_memory = NULL; + } + + if (exynos_camera->capture_yuv_buffer != NULL) { + free(exynos_camera->capture_yuv_buffer); + exynos_camera->capture_yuv_buffer = NULL; + } + + if (exynos_camera->capture_jpeg_buffer != NULL) { + free(exynos_camera->capture_jpeg_buffer); + exynos_camera->capture_jpeg_buffer = NULL; + } + + exynos_camera->capture_enabled = 0; +} + +int exynos_camera_capture_setup(struct exynos_camera *exynos_camera) +{ + struct exynos_camera_capture_listener *listener; + struct list_head *list; + int width, height, format; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + // No listener left + if (exynos_camera->capture_listeners == NULL && exynos_camera->capture_enabled) { + ALOGE("%s: no listener left", __func__); + exynos_camera_capture_stop(exynos_camera); + return 0; + } + + width = height = format = 0; + + list = (struct list_head *) exynos_camera->capture_listeners; + while (list != NULL) { + listener = (struct exynos_camera_capture_listener *) list; + + if (listener->width >= width && listener->height >= height) { + width = listener->width; + height = listener->height; + format = listener->format; + } + +list_continue: + list = list->next; + } + + // Only picture is listening, but we need some preview size anyway + if (format == V4L2_PIX_FMT_YUYV && (width == 0 || height == 0)) { + width = exynos_camera->preview_width; + height = exynos_camera->preview_height; + } + + ALOGD("%s: Selected width: %d, height: %d, format: 0x%x", __func__, width, height, format); + + if (!exynos_camera->capture_enabled) { + exynos_camera->capture_width = width; + exynos_camera->capture_height = height; + exynos_camera->capture_format = format; + + rc = exynos_camera_capture_start(exynos_camera,0); + if (rc < 0) { + ALOGE("%s: Unable to start capture", __func__); + return -1; + } + } else if ((exynos_camera->capture_width != width || exynos_camera->capture_height != height || exynos_camera->capture_format != format) + && !exynos_camera->recording_thread_enabled) { + exynos_camera_capture_stop(exynos_camera); + + exynos_camera->capture_width = width; + exynos_camera->capture_height = height; + exynos_camera->capture_format = format; + + rc = exynos_camera_capture_start(exynos_camera,1); + if (rc < 0) { + ALOGE("%s: Unable to start capture", __func__); + return -1; + } + } + + return 0; +} + +struct exynos_camera_capture_listener *exynos_camera_capture_listener_register( + struct exynos_camera *exynos_camera, int width, int height, int format, + int (*callback)(struct exynos_camera *exynos_camera, struct exynos_camera_buffer *buffers, int buffers_count)) +{ + struct exynos_camera_capture_listener *listener = NULL; + struct list_head *list_end; + struct list_head *list; + int rc; + + ALOGE("%s: ", __func__); + + if (exynos_camera == NULL || callback == NULL) + return NULL; + + pthread_mutex_lock(&exynos_camera->capture_mutex); + + listener = calloc(1, sizeof(struct exynos_camera_capture_listener)); + if (listener == NULL) + goto error; + + listener->width = width; + listener->height = height; + listener->format = format; + listener->callback = callback; + listener->busy = 0; + + list_end = (struct list_head *) exynos_camera->capture_listeners; + while (list_end != NULL && list_end->next != NULL) + list_end = list_end->next; + + list = (struct list_head *) listener; + list_head_insert(list, list_end, NULL); + + if (exynos_camera->capture_listeners == NULL) + exynos_camera->capture_listeners = listener; + + rc = exynos_camera_capture_setup(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to setup capture", __func__); + goto error; + } + + rc = 0; + goto complete; + +error: + listener = NULL; + +complete: + pthread_mutex_unlock(&exynos_camera->capture_mutex); + + return listener; +} + +void exynos_camera_capture_listener_unregister( + struct exynos_camera *exynos_camera, + struct exynos_camera_capture_listener *listener) +{ + struct list_head *list; + int rc; + + if (exynos_camera == NULL || listener == NULL) + return; + + pthread_mutex_lock(&exynos_camera->capture_mutex); + + list = (struct list_head *) exynos_camera->capture_listeners; + while (list != NULL) { + if ((void *) list == (void *) listener) { + list_head_remove(list); + + if ((void *) list == (void *) exynos_camera->capture_listeners) + exynos_camera->capture_listeners = (struct exynos_camera_capture_listener *) list->next; + + memset(listener, 0, sizeof(struct exynos_camera_capture_listener)); + free(listener); + + break; + } +list_continue: + list = list->next; + } + + rc = exynos_camera_capture_setup(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to setup capture", __func__); + goto complete; + } + +complete: + pthread_mutex_unlock(&exynos_camera->capture_mutex); +} + +// Preview + +int exynos_camera_preview_output_start(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->preview_output_enabled) { + ALOGE("Preview was already started!"); + return -1; + } + + output = &exynos_camera->preview_output; + + memset(output, 0, sizeof(struct exynos_v4l2_output)); + output->v4l2_id = 1; + output->width = exynos_camera->preview_width; + output->height = exynos_camera->preview_height; + output->format = exynos_camera->preview_format; + output->buffer_width = exynos_camera->preview_buffer.width; + output->buffer_height = exynos_camera->preview_buffer.height; + output->buffer_format = exynos_camera->preview_buffer.format; + output->buffers_count = EXYNOS_CAMERA_PREVIEW_BUFFERS_COUNT; + + rc = exynos_v4l2_output_start(exynos_camera, output); + if (rc < 0) { + ALOGE("%s: Unable to start preview output", __func__); + goto error; + } + exynos_camera->preview_output_enabled = 1; + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + return rc; +} + +void exynos_camera_preview_output_stop(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->preview_output_enabled) { + ALOGE("Preview was already stopped!"); + return; + } + + output = &exynos_camera->preview_output; + + exynos_v4l2_output_stop(exynos_camera, output); + + exynos_camera->preview_output_enabled = 0; +} + +int exynos_camera_preview_callback(struct exynos_camera *exynos_camera, + struct exynos_camera_buffer *buffers, int buffers_count) +{ + struct exynos_camera_buffer *buffer = NULL; + int width, height, format; + int buffer_width, buffer_height, buffer_format; + int rc; + int i; + + if (exynos_camera == NULL || buffers == NULL || buffers_count <= 0) + return -EINVAL; + + //ALOGD("%s()", __func__); + + if (exynos_camera->preview_listener == NULL) + return -1; + + if (exynos_camera->preview_listener->busy) { + ALOGE("%s: Dropping buffer", __func__); + return 0; + } + + exynos_camera->preview_listener->busy = 1; + + width = exynos_camera->preview_width; + height = exynos_camera->preview_height; + format = exynos_camera->preview_format; + + for (i = 0; i < buffers_count; i++) { + if (buffers->format == V4L2_PIX_FMT_JPEG) + goto buffers_continue; + + // Optimal buffer + if (buffers->width == width && buffers->height == height) { + buffer = buffers; + break; + } + + // Might-work buffer, but not optimal + buffer = buffers; + +buffers_continue: + buffers = (struct exynos_camera_buffer *) ((unsigned char *) buffers + sizeof(struct exynos_camera_buffer)); + } + + if (buffer == NULL) { + ALOGE("%s: Unable to find an appropriate buffer for preview", __func__); + exynos_camera->preview_listener->busy = 0; + return 0; + } + + buffer_width = buffer->width; + buffer_height = buffer->height; + buffer_format = buffer->format; + + pthread_mutex_lock(&exynos_camera->preview_mutex); + + if (buffer_width != width || buffer_height != height || buffer_format != format) { + if (!exynos_camera->preview_output_enabled) { + memcpy(&exynos_camera->preview_buffer, buffer, sizeof(struct exynos_camera_buffer)); + + rc = exynos_camera_preview_output_start(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to start preview", __func__); + goto error; + } + } else if (exynos_camera->preview_buffer.width != buffer_width || exynos_camera->preview_buffer.height != buffer_height || exynos_camera->preview_buffer.format != buffer_format) { + exynos_camera_preview_output_stop(exynos_camera); + + memcpy(&exynos_camera->preview_buffer, buffer, sizeof(struct exynos_camera_buffer)); + + rc = exynos_camera_preview_output_start(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to start preview", __func__); + goto error; + } + } else { + memcpy(&exynos_camera->preview_buffer, buffer, sizeof(struct exynos_camera_buffer)); + } + } else { + // The buffer format exactly matches our expectations + if (exynos_camera->preview_output_enabled) + exynos_camera_preview_output_stop(exynos_camera); + + memcpy(&exynos_camera->preview_buffer, buffer, sizeof(struct exynos_camera_buffer)); + } + + pthread_mutex_unlock(&exynos_camera->preview_lock_mutex); + + pthread_mutex_unlock(&exynos_camera->preview_mutex); + + rc = 0; + goto complete; + +error: + pthread_mutex_unlock(&exynos_camera->preview_mutex); + + exynos_camera->preview_listener->busy = 0; + + rc = -1; + +complete: + return rc; +} + +int exynos_camera_preview(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + int width, height, format; + buffer_handle_t *window_buffer; + void *window_data; + int window_stride; + camera_memory_t *memory; + void *memory_pointer; + int memory_index; + int memory_size; + int rc; + + if (exynos_camera == NULL) + goto error; + +// ALOGD("%s()", __func__); + + width = exynos_camera->preview_width; + height = exynos_camera->preview_height; + format = exynos_camera->preview_format; + + output = &exynos_camera->preview_output; + + if (exynos_camera->preview_output_enabled) { + rc = exynos_v4l2_output(exynos_camera, output, exynos_camera->preview_buffer.address); + if (rc < 0) { + ALOGE("%s: Unable to output preview", __func__); + goto error; + } + + memory = output->memory; + memory_index = output->memory_index; + memory_pointer = (void *) ((unsigned char *) memory->data + output->buffer_length * memory_index); + memory_size = output->buffer_length; + } else { + // In that case, we can directly use the capture memory + memory = exynos_camera->capture_memory; + memory_index = exynos_camera->capture_memory_index; + memory_pointer = exynos_camera->preview_buffer.pointer; + memory_size = exynos_camera->preview_buffer.length; + } + + if (exynos_camera->preview_window != NULL && exynos_camera->gralloc != NULL) { + exynos_camera->preview_window->dequeue_buffer(exynos_camera->preview_window, &window_buffer, &window_stride); + exynos_camera->gralloc->lock(exynos_camera->gralloc, *window_buffer, GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, width, height, &window_data); + + if (window_data == NULL) { + ALOGE("%s: Unable to lock gralloc", __func__); + goto error; + } + + memcpy(window_data, memory_pointer, memory_size); + + exynos_camera->gralloc->unlock(exynos_camera->gralloc, *window_buffer); + exynos_camera->preview_window->enqueue_buffer(exynos_camera->preview_window, window_buffer); + } + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_PREVIEW_FRAME) && EXYNOS_CAMERA_CALLBACK_DEFINED(data) && !exynos_camera->callback_lock) { + exynos_camera->callbacks.data(CAMERA_MSG_PREVIEW_FRAME, memory, memory_index, NULL, exynos_camera->callbacks.user); + } + + if (exynos_camera->preview_output_enabled) { + rc = exynos_v4l2_output_release(exynos_camera, output); + if (rc < 0) { + ALOGE("%s: Unable to release preview output", __func__); + goto error; + } + } + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + exynos_camera->preview_listener->busy = 0; + + return rc; +} + +void *exynos_camera_preview_thread(void *data) +{ + struct exynos_camera *exynos_camera; + int rc; + + if (data == NULL) + return NULL; + + exynos_camera = (struct exynos_camera *) data; + + ALOGE("%s: Starting thread", __func__); + exynos_camera->preview_thread_running = 1; + + while (exynos_camera->preview_thread_enabled) { + pthread_mutex_lock(&exynos_camera->preview_lock_mutex); + + pthread_mutex_lock(&exynos_camera->preview_mutex); + + if (exynos_camera->preview_listener == NULL) { + pthread_mutex_unlock(&exynos_camera->preview_mutex); + break; + } + + if (exynos_camera->preview_listener->busy) { + rc = exynos_camera_preview(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to preview", __func__); + pthread_mutex_unlock(&exynos_camera->preview_mutex); + break; + } + } + + pthread_mutex_unlock(&exynos_camera->preview_mutex); + } + + exynos_camera->preview_thread_running = 0; + ALOGE("%s: Exiting thread", __func__); + + return NULL; +} + +int exynos_camera_preview_thread_start(struct exynos_camera *exynos_camera) +{ + struct exynos_camera_capture_listener *listener; + pthread_attr_t thread_attr; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->preview_thread_enabled) { + ALOGE("Preview thread was already started!"); + return -1; + } + + pthread_mutex_init(&exynos_camera->preview_mutex, NULL); + pthread_mutex_init(&exynos_camera->preview_lock_mutex, NULL); + + // Initial lock + pthread_mutex_lock(&exynos_camera->preview_lock_mutex); + + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + + exynos_camera->preview_thread_enabled = 1; + + rc = pthread_create(&exynos_camera->preview_thread, &thread_attr, exynos_camera_preview_thread, (void *) exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to create thread", __func__); + goto error; + } + + listener = exynos_camera_capture_listener_register(exynos_camera, exynos_camera->preview_width, exynos_camera->preview_height, exynos_camera->preview_format, exynos_camera_preview_callback); + if (listener == NULL) { + ALOGE("%s: Unable to register capture listener", __func__); + goto error; + } + + exynos_camera->preview_listener = listener; + + rc = 0; + goto complete; + +error: + pthread_mutex_destroy(&exynos_camera->preview_mutex); + pthread_mutex_destroy(&exynos_camera->preview_lock_mutex); + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_preview_thread_stop(struct exynos_camera *exynos_camera) +{ + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->preview_thread_enabled) { + ALOGE("Preview thread was already stopped!"); + return; + } + + if (exynos_camera->preview_listener != NULL) { + exynos_camera_capture_listener_unregister(exynos_camera, exynos_camera->preview_listener); + exynos_camera->preview_listener = NULL; + } + + exynos_camera->preview_thread_enabled = 0; + + pthread_mutex_unlock(&exynos_camera->preview_lock_mutex); + + // Wait for the thread to end + i = 0; + while (exynos_camera->preview_thread_running) { + if (i++ > 10000) { + ALOGE("Preview thread is taking too long to end, something is going wrong"); + break; + } + usleep(100); + } + + if (exynos_camera->preview_output_enabled) { + pthread_mutex_lock(&exynos_camera->preview_mutex); + exynos_camera_preview_output_stop(exynos_camera); + pthread_mutex_unlock(&exynos_camera->preview_mutex); + } + + pthread_mutex_destroy(&exynos_camera->preview_mutex); + pthread_mutex_destroy(&exynos_camera->preview_lock_mutex); + + // Invalidate the preview window + exynos_camera->preview_window = NULL; +} + +// Picture + +int exynos_camera_picture_callback(struct exynos_camera *exynos_camera, + struct exynos_camera_buffer *buffers, int buffers_count) +{ + struct exynos_camera_buffer *jpeg_buffer = NULL; + struct exynos_camera_buffer *jpeg_thumbnail_buffer = NULL; + struct exynos_camera_buffer *yuv_buffer = NULL; + struct exynos_camera_buffer *yuv_thumbnail_buffer = NULL; + int width, height; + int thumbnail_width, thumbnail_height; + int rc; + int i; + + if (exynos_camera == NULL || buffers == NULL || buffers_count <= 0) + return -EINVAL; + + ALOGD("%s()", __func__); + + width = exynos_camera->picture_width; + height = exynos_camera->picture_height; + thumbnail_width = exynos_camera->jpeg_thumbnail_width; + thumbnail_height = exynos_camera->jpeg_thumbnail_height; + + if (exynos_camera->picture_completed){ + ALOGE("%s: exynos_camera->picture_completed", __func__); + return -1; + } + + if (exynos_camera->picture_listener == NULL){ + ALOGE("%s: exynos_camera->picture_listener == NULL", __func__); + return -1; + } + if (exynos_camera->picture_listener->busy) { + ALOGE("%s: Dropping buffer", __func__); + return 0; + } + + pthread_mutex_lock(&exynos_camera->picture_mutex); + + if (!exynos_camera->picture_enabled) { + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_CAPTURE, 0); + if (rc < 0) { + ALOGE("%s: Unable to set capture", __func__); + goto error; + } + + exynos_camera->picture_enabled = 1; + + pthread_mutex_unlock(&exynos_camera->picture_mutex); + return 0; + } + + pthread_mutex_unlock(&exynos_camera->picture_mutex); + + exynos_camera->picture_listener->busy = 1; + + // Let's assume the picture format is JPEG + + for (i = 0; i < buffers_count; i++) { + if (buffers->format == V4L2_PIX_FMT_JPEG) { + if (buffers->width == width && buffers->height == height) + jpeg_buffer = buffers; + else if (buffers->width == thumbnail_width && buffers->height == thumbnail_height) + jpeg_thumbnail_buffer = buffers; + } else { + if (buffers->width >= width && buffers->height >= height){ + yuv_buffer = buffers; + } + if (buffers->width >= thumbnail_width && buffers->height >= thumbnail_height){ + yuv_thumbnail_buffer = buffers; + } + } + +buffers_continue: + buffers = (struct exynos_camera_buffer *) ((unsigned char *) buffers + sizeof(struct exynos_camera_buffer)); + } + + if (jpeg_buffer == NULL && yuv_buffer == NULL) { + ALOGE("%s: Unable to find an appropriate buffer for picture", __func__); + exynos_camera->picture_listener->busy = 0; + return 0; + } + + pthread_mutex_lock(&exynos_camera->picture_mutex); + + if (jpeg_buffer == NULL){ + memset(&exynos_camera->picture_jpeg_buffer, 0, sizeof(exynos_camera->picture_jpeg_buffer)); + }else{ + memcpy(&exynos_camera->picture_jpeg_buffer, jpeg_buffer, sizeof(struct exynos_camera_buffer)); + } + if (jpeg_thumbnail_buffer == NULL){ + memset(&exynos_camera->picture_jpeg_thumbnail_buffer, 0, sizeof(exynos_camera->picture_jpeg_thumbnail_buffer)); + }else{ + memcpy(&exynos_camera->picture_jpeg_thumbnail_buffer, jpeg_thumbnail_buffer, sizeof(struct exynos_camera_buffer)); + } + if (yuv_buffer == NULL){ + memset(&exynos_camera->picture_yuv_buffer, 0, sizeof(exynos_camera->picture_yuv_buffer)); + }else{ + memcpy(&exynos_camera->picture_yuv_buffer, yuv_buffer, sizeof(struct exynos_camera_buffer)); + } + if (yuv_thumbnail_buffer == NULL){ + memset(&exynos_camera->picture_yuv_thumbnail_buffer, 0, sizeof(exynos_camera->picture_yuv_thumbnail_buffer)); + }else{ + memcpy(&exynos_camera->picture_yuv_thumbnail_buffer, yuv_thumbnail_buffer, sizeof(struct exynos_camera_buffer)); + } + pthread_mutex_unlock(&exynos_camera->picture_lock_mutex); + + pthread_mutex_unlock(&exynos_camera->picture_mutex); + + rc = 0; + goto complete; + +error: + pthread_mutex_unlock(&exynos_camera->picture_mutex); + + exynos_camera->picture_listener->busy = 0; + + rc = -1; + +complete: + return rc; +} + +int exynos_camera_picture(struct exynos_camera *exynos_camera) +{ + struct exynos_camera_buffer *jpeg_buffer; + struct exynos_camera_buffer *jpeg_thumbnail_buffer; + struct exynos_camera_buffer *yuv_buffer; + struct exynos_camera_buffer *yuv_thumbnail_buffer; + struct exynos_v4l2_output output; + struct exynos_jpeg jpeg; + struct exynos_exif exif; + int output_enabled = 0; + int width, height, format; + int buffer_width, buffer_height, buffer_format, buffer_address; + camera_memory_t *memory = NULL; + int memory_size; + unsigned char *p; + camera_memory_t *jpeg_memory = NULL; + void *jpeg_data = NULL; + int jpeg_size = 0; + camera_memory_t *jpeg_thumbnail_memory = NULL; + void *jpeg_thumbnail_data = NULL; + int jpeg_thumbnail_size = 0; + void *yuv_data = NULL; + int yuv_address; + int yuv_size = 0; + void *yuv_thumbnail_data = NULL; + int yuv_thumbnail_address; + int yuv_thumbnail_size = 0; + int rc; + + if (exynos_camera == NULL) + goto error; + + ALOGD("%s()", __func__); + + jpeg_buffer = &exynos_camera->picture_jpeg_buffer; + jpeg_thumbnail_buffer = &exynos_camera->picture_jpeg_thumbnail_buffer; + yuv_buffer = &exynos_camera->picture_yuv_buffer; + yuv_thumbnail_buffer = &exynos_camera->picture_yuv_thumbnail_buffer; + + if (jpeg_buffer->pointer != NULL && jpeg_buffer->length > 0) { + jpeg_data = jpeg_buffer->pointer; + jpeg_size = jpeg_buffer->length; + } + + if (jpeg_thumbnail_buffer->pointer != NULL && jpeg_thumbnail_buffer->length > 0) { + jpeg_thumbnail_data = jpeg_thumbnail_buffer->pointer; + jpeg_thumbnail_size = jpeg_thumbnail_buffer->length; + } + + if (yuv_buffer->pointer != NULL && yuv_buffer->length > 0) { + yuv_data = yuv_buffer->pointer; + yuv_address = yuv_buffer->address; + yuv_size = yuv_buffer->length; + } + + if (yuv_thumbnail_buffer->pointer != NULL && yuv_thumbnail_buffer->length > 0) { + yuv_thumbnail_data = yuv_thumbnail_buffer->pointer; + yuv_thumbnail_address = yuv_thumbnail_buffer->address; + yuv_thumbnail_size = yuv_thumbnail_buffer->length; + } + + // JPEG + + if (jpeg_data == NULL) { + if (yuv_data == NULL || yuv_size <= 0) { + ALOGE("%s: Unable to create jpeg without an YUV buffer", __func__); + goto error; + } + + width = exynos_camera->picture_width; + height = exynos_camera->picture_height; + format = yuv_buffer->format; + + buffer_width = yuv_buffer->width; + buffer_height = yuv_buffer->height; + buffer_format = yuv_buffer->format; + buffer_address = yuv_buffer->address; + + if (width != buffer_width && height != buffer_height) { + format = EXYNOS_CAMERA_PICTURE_OUTPUT_FORMAT; + + memset(&output, 0, sizeof(output)); + output.v4l2_id = 2; + output.width = width; + output.height = height; + output.format = format; + output.buffer_width = buffer_width; + output.buffer_height = buffer_height; + output.buffer_format = buffer_format; + output.buffers_count = 1; + + rc = exynos_v4l2_output_start(exynos_camera, &output); + if (rc < 0) { + ALOGE("%s: Unable to start picture output", __func__); + goto error; + } + + rc = exynos_v4l2_output(exynos_camera, &output, buffer_address); + if (rc < 0) { + ALOGE("%s: Unable to output picture", __func__); + goto error; + } + + output_enabled = 1; + + yuv_data = output.memory->data; + yuv_address = output.memory_address; + yuv_size = output.buffer_length; + } + + memset(&jpeg, 0, sizeof(jpeg)); + jpeg.width = width; + jpeg.height = height; + jpeg.format = format; + jpeg.quality = exynos_camera->jpeg_quality; + + rc = exynos_jpeg_start(exynos_camera, &jpeg); + if (rc < 0) { + ALOGE("%s: Unable to start jpeg", __func__); + goto error; + } + + if (jpeg.memory_in_pointer == NULL) { + ALOGE("%s: Invalid memory input pointer", __func__); + goto error; + } + + memcpy(jpeg.memory_in_pointer, yuv_data, yuv_size); + + rc = exynos_jpeg(exynos_camera, &jpeg); + if (rc < 0) { + ALOGE("%s: Unable to jpeg", __func__); + goto error; + } + + jpeg_size = jpeg.memory_out_size; + if (jpeg_size <= 0) { + ALOGE("%s: Invalid jpeg size", __func__); + goto error; + } + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + jpeg_memory = exynos_camera->callbacks.request_memory(-1, jpeg_size, 1, exynos_camera->callbacks.user); + if (jpeg_memory == NULL || jpeg_memory->data == NULL || jpeg_memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + jpeg_data = jpeg_memory->data; + + memcpy(jpeg_data, jpeg.memory_out_pointer, jpeg_size); + + exynos_jpeg_stop(exynos_camera, &jpeg); + + if (output_enabled) { + exynos_v4l2_output_stop(exynos_camera, &output); + output_enabled = 0; + } + } + + // Thumbnail + + if (jpeg_thumbnail_data == NULL) { + if (yuv_thumbnail_data == NULL || yuv_thumbnail_size <= 0) { + ALOGE("%s: Unable to create jpeg thumbnail without an YUV buffer", __func__); + goto error; + } + + width = exynos_camera->jpeg_thumbnail_width; + height = exynos_camera->jpeg_thumbnail_height; + format = yuv_thumbnail_buffer->format; + + buffer_width = yuv_thumbnail_buffer->width; + buffer_height = yuv_thumbnail_buffer->height; + buffer_format = yuv_thumbnail_buffer->format; + buffer_address = yuv_thumbnail_buffer->address; + + if (width != buffer_width && height != buffer_height) { + format = EXYNOS_CAMERA_PICTURE_OUTPUT_FORMAT; + + memset(&output, 0, sizeof(output)); + output.v4l2_id = 2; + output.width = width; + output.height = height; + output.format = format; + output.buffer_width = buffer_width; + output.buffer_height = buffer_height; + output.buffer_format = buffer_format; + output.buffers_count = 1; + + rc = exynos_v4l2_output_start(exynos_camera, &output); + if (rc < 0) { + ALOGE("%s: Unable to start thumbnail picture output", __func__); + goto error; + } + + output_enabled = 1; + + rc = exynos_v4l2_output(exynos_camera, &output, buffer_address); + if (rc < 0) { + ALOGE("%s: Unable to output thumbnail picture", __func__); + goto error; + } + + yuv_thumbnail_data = output.memory->data; + yuv_thumbnail_address = output.memory_address; + yuv_thumbnail_size = output.buffer_length; + } + + memset(&jpeg, 0, sizeof(jpeg)); + jpeg.width = width; + jpeg.height = height; + jpeg.format = format; + jpeg.quality = exynos_camera->jpeg_thumbnail_quality; + + rc = exynos_jpeg_start(exynos_camera, &jpeg); + if (rc < 0) { + ALOGE("%s: Unable to start jpeg", __func__); + goto error; + } + + if (jpeg.memory_in_pointer == NULL) { + ALOGE("%s: Invalid memory input pointer", __func__); + goto error; + } + + memcpy(jpeg.memory_in_pointer, yuv_thumbnail_data, yuv_thumbnail_size); + + rc = exynos_jpeg(exynos_camera, &jpeg); + if (rc < 0) { + ALOGE("%s: Unable to jpeg", __func__); + goto error; + } + + jpeg_thumbnail_size = jpeg.memory_out_size; + if (jpeg_thumbnail_size <= 0) { + ALOGE("%s: Invalid jpeg size", __func__); + goto error; + } + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + jpeg_thumbnail_memory = exynos_camera->callbacks.request_memory(-1, jpeg_thumbnail_size, 1, exynos_camera->callbacks.user); + if (jpeg_thumbnail_memory == NULL || jpeg_thumbnail_memory->data == NULL || jpeg_thumbnail_memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + jpeg_thumbnail_data = jpeg_thumbnail_memory->data; + + memcpy(jpeg_thumbnail_data, jpeg.memory_out_pointer, jpeg_thumbnail_size); + + exynos_jpeg_stop(exynos_camera, &jpeg); + + if (output_enabled) { + exynos_v4l2_output_stop(exynos_camera, &output); + output_enabled = 0; + } + } + + // EXIF + + memset(&exif, 0, sizeof(exif)); + exif.jpeg_thumbnail_data = jpeg_thumbnail_data; + exif.jpeg_thumbnail_size = jpeg_thumbnail_size; + + rc = exynos_exif_start(exynos_camera, &exif); + if (rc < 0) { + ALOGE("%s: Unable to start exif", __func__); + goto error; + } + + rc = exynos_exif(exynos_camera, &exif); + if (rc < 0) { + ALOGE("%s: Unable to exif", __func__); + goto error; + } + + memory_size = exif.memory_size + jpeg_size; + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(-1, memory_size, 1, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + p = (unsigned char *) memory->data; + + // Copy the first two bytes of the JPEG picture + memcpy(p, jpeg_data, 2); + p += 2; + + // Copy the EXIF data + memcpy(p, exif.memory->data, exif.memory_size); + p += exif.memory_size; + + // Copy the JPEG picture + memcpy(p, (void *) ((unsigned char *) jpeg_data + 2), jpeg_size - 2); + + exynos_exif_stop(exynos_camera, &exif); + + exynos_camera->picture_memory = memory; + + rc = 0; + goto complete; + +error: + if (output_enabled) + exynos_v4l2_output_stop(exynos_camera, &output); + + if (memory != NULL && memory->release != NULL) { + memory->release(memory); + exynos_camera->picture_memory = NULL; + } + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_ERROR) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_ERROR, -1, 0, exynos_camera->callbacks.user); + + rc = -1; + +complete: + if (jpeg_memory != NULL && jpeg_memory->release != NULL) + jpeg_memory->release(jpeg_memory); + + if (jpeg_thumbnail_memory != NULL && jpeg_thumbnail_memory->release != NULL) + jpeg_thumbnail_memory->release(jpeg_thumbnail_memory); + + exynos_camera->picture_completed = 1; + exynos_camera->picture_listener->busy = 0; + + return rc; +} + +void *exynos_camera_picture_thread(void *data) +{ + struct exynos_camera *exynos_camera; + int rc; + + if (data == NULL) + return NULL; + + exynos_camera = (struct exynos_camera *) data; + + ALOGE("%s: Starting thread", __func__); + exynos_camera->picture_thread_running = 1; + + exynos_camera->picture_completed = 0; + + while (exynos_camera->picture_thread_enabled) { + pthread_mutex_lock(&exynos_camera->picture_lock_mutex); + pthread_mutex_lock(&exynos_camera->picture_mutex); + + if (exynos_camera->picture_listener == NULL) { + pthread_mutex_unlock(&exynos_camera->picture_mutex); + break; + } + + if (exynos_camera->picture_listener->busy) { + rc = exynos_camera_picture(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to take picture", __func__); + pthread_mutex_unlock(&exynos_camera->picture_mutex); + break; + } + } + + pthread_mutex_unlock(&exynos_camera->picture_mutex); + + if (exynos_camera->picture_completed) { + ALOGE("%s: exynos_camera->picture_completed", __func__); + exynos_camera->picture_thread_running = 0; + exynos_camera_picture_thread_stop(exynos_camera); + break; + } + } + + exynos_camera->picture_thread_running = 0; + ALOGE("%s: Exiting thread", __func__); + + return NULL; +} + +int exynos_camera_picture_thread_start(struct exynos_camera *exynos_camera) +{ + struct exynos_camera_capture_listener *listener; + pthread_attr_t thread_attr; + int format; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->picture_thread_enabled) { + ALOGE("Picture thread was already started!"); + return 0; + } + + if (exynos_camera->camera_picture_format) + format = exynos_camera->camera_picture_format; + else + format = exynos_camera->picture_format; + + pthread_mutex_init(&exynos_camera->picture_mutex, NULL); + + pthread_mutex_init(&exynos_camera->picture_lock_mutex, NULL); + + // Initial lock + pthread_mutex_lock(&exynos_camera->picture_lock_mutex); + + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + + exynos_camera->picture_thread_enabled = 1; + + rc = pthread_create(&exynos_camera->picture_thread, &thread_attr, exynos_camera_picture_thread, (void *) exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to create thread", __func__); + goto error; + } + + format = exynos_camera->picture_format; + + listener = exynos_camera_capture_listener_register(exynos_camera, exynos_camera->picture_width, exynos_camera->picture_height, format, exynos_camera_picture_callback); + if (listener == NULL) { + ALOGE("%s: Unable to register picture capture listener", __func__); + goto error; + } + + exynos_camera->picture_listener = listener; + exynos_camera->picture_enabled = 1; + + rc = 0; + goto complete; + +error: + pthread_mutex_destroy(&exynos_camera->picture_mutex); + pthread_mutex_destroy(&exynos_camera->picture_lock_mutex); + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_picture_thread_stop(struct exynos_camera *exynos_camera) +{ + camera_memory_t *memory; + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->picture_thread_enabled) { + ALOGE("Picture thread was already stopped!"); + return; + } + + memory = exynos_camera->picture_memory; + + if (exynos_camera->picture_listener != NULL) { + exynos_camera_capture_listener_unregister(exynos_camera, exynos_camera->picture_listener); + exynos_camera->picture_listener = NULL; + } + + exynos_camera->picture_thread_enabled = 0; + + pthread_mutex_unlock(&exynos_camera->picture_lock_mutex); + + // Wait for the thread to end + i = 0; + while (exynos_camera->picture_thread_running) { + if (i++ > 10000) { + ALOGE("Picture thread is taking too long to end, something is going wrong"); + break; + } + usleep(100); + } + + if (exynos_camera->picture_enabled) { + pthread_mutex_lock(&exynos_camera->picture_mutex); + exynos_camera->picture_enabled = 0; + pthread_mutex_unlock(&exynos_camera->picture_mutex); + } + + pthread_mutex_destroy(&exynos_camera->picture_mutex); + pthread_mutex_destroy(&exynos_camera->picture_lock_mutex); + + if (exynos_camera->picture_completed && memory != NULL) { + // It is important to return at this point (and not before) for burst + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_SHUTTER) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_SHUTTER, 0, 0, exynos_camera->callbacks.user); + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_COMPRESSED_IMAGE) && EXYNOS_CAMERA_CALLBACK_DEFINED(data) && !exynos_camera->callback_lock) + exynos_camera->callbacks.data(CAMERA_MSG_COMPRESSED_IMAGE, memory, 0, NULL, exynos_camera->callbacks.user); + + if (memory->release != NULL) { + memory->release(memory); + exynos_camera->picture_memory = NULL; + } + } +} + +// Recording + +int exynos_camera_recording_output_start(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->recording_output_enabled) { + ALOGE("Recording was already started!"); + return -1; + } + + output = &exynos_camera->recording_output; + + memset(output, 0, sizeof(struct exynos_v4l2_output)); + output->v4l2_id = 3; + output->width = exynos_camera->recording_width; + output->height = exynos_camera->recording_height; + output->format = exynos_camera->recording_format; + output->buffer_width = exynos_camera->recording_buffer.width; + output->buffer_height = exynos_camera->recording_buffer.height; + output->buffer_format = exynos_camera->recording_buffer.format; + output->buffers_count = EXYNOS_CAMERA_RECORDING_BUFFERS_COUNT; + + rc = exynos_v4l2_output_start(exynos_camera, output); + if (rc < 0) { + ALOGE("%s: Unable to start recording output", __func__); + goto error; + } + + exynos_camera->recording_output_enabled = 1; + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + return rc; +} + +void exynos_camera_recording_output_stop(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->recording_output_enabled) { + ALOGE("Recording was already stopped!"); + return; + } + + output = &exynos_camera->recording_output; + + exynos_v4l2_output_stop(exynos_camera, output); + + exynos_camera->recording_output_enabled = 0; +} + +int exynos_camera_recording_callback(struct exynos_camera *exynos_camera, + struct exynos_camera_buffer *buffers, int buffers_count) +{ + struct exynos_camera_buffer *buffer = NULL; + int width, height, format; + int buffer_width, buffer_height, buffer_format; + int rc; + int i; + + if (exynos_camera == NULL || buffers == NULL || buffers_count <= 0) + return -EINVAL; + + //ALOGD("%s()", __func__); + + if (exynos_camera->recording_listener == NULL) + return -1; + + if (exynos_camera->recording_listener->busy) { + ALOGE("%s: Dropping buffer", __func__); + return 0; + } + + exynos_camera->recording_listener->busy = 1; + + width = exynos_camera->recording_width; + height = exynos_camera->recording_height; + format = exynos_camera->recording_format; + + for (i = 0; i < buffers_count; i++) { + if (buffers->format == V4L2_PIX_FMT_JPEG){ + goto buffers_continue;} + + // Optimal buffer + if (buffers->width == width && buffers->height == height) { + buffer = buffers; + break; + } + + // Might-work buffer, but not optimal + buffer = buffers; + +buffers_continue: + buffers = (struct exynos_camera_buffer *) ((unsigned char *) buffers + sizeof(struct exynos_camera_buffer)); + } + + if (buffer == NULL) { + ALOGE("%s: Unable to find an appropriate buffer for recording", __func__); + exynos_camera->recording_listener->busy = 0; + return 0; + } + + buffer_width = buffer->width; + buffer_height = buffer->height; + buffer_format = buffer->format; + + pthread_mutex_lock(&exynos_camera->recording_mutex); + + if (!exynos_camera->recording_output_enabled) { + memcpy(&exynos_camera->recording_buffer, buffer, sizeof(struct exynos_camera_buffer)); + + rc = exynos_camera_recording_output_start(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to start recording", __func__); + goto error; + } + } else if (exynos_camera->recording_buffer.width != buffer_width || exynos_camera->recording_buffer.height != buffer_height || exynos_camera->recording_buffer.format != buffer_format) { + exynos_camera_recording_output_stop(exynos_camera); + + memcpy(&exynos_camera->recording_buffer, buffer, sizeof(struct exynos_camera_buffer)); + + rc = exynos_camera_recording_output_start(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to start recording", __func__); + goto error; + } + } else { + memcpy(&exynos_camera->recording_buffer, buffer, sizeof(struct exynos_camera_buffer)); + } + + pthread_mutex_unlock(&exynos_camera->recording_lock_mutex); + + pthread_mutex_unlock(&exynos_camera->recording_mutex); + + rc = 0; + goto complete; + +error: + pthread_mutex_unlock(&exynos_camera->recording_mutex); + + exynos_camera->recording_listener->busy = 0; + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_recording_frame_release(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + int rc; + + if (exynos_camera == NULL) + return; + +// ALOGD("%s()", __func__); + + output = &exynos_camera->recording_output; + + if (!exynos_camera->recording_output_enabled) { + ALOGE("%s: Recording output should always be enabled", __func__); + return; + } + + rc = exynos_v4l2_output_release(exynos_camera, output); + if (rc < 0) { + ALOGE("%s: Unable to release recording output", __func__); + return; + } +} + +int exynos_camera_recording(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + struct exynos_camera_addrs *addrs; + int width, height, format; + camera_memory_t *memory; + int memory_address; + int memory_index; + int buffer_length; + int buffers_count; + nsecs_t timestamp; + int rc; + + if (exynos_camera == NULL) + goto error; + + ALOGD("%s()", __func__); + + width = exynos_camera->recording_width; + height = exynos_camera->recording_height; + format = exynos_camera->recording_format; + + output = &exynos_camera->recording_output; + + buffer_length = exynos_camera->recording_buffer_length; + buffers_count = exynos_camera->recording_buffers_count; + + timestamp = systemTime(1); + + if (!exynos_camera->recording_output_enabled) { + ALOGE("%s: Recording output should always be enabled", __func__); + goto error; + } + + rc = exynos_v4l2_output(exynos_camera, output, exynos_camera->recording_buffer.address); + if (rc < 0) { + ALOGE("%s: Unable to output recording", __func__); + goto error; + } + + if (exynos_camera->recording_metadata) { + memory = exynos_camera->recording_memory; + memory_index = exynos_camera->recording_memory_index; + memory_address = output->memory_address + output->buffer_length * output->memory_index; + + addrs = (struct exynos_camera_addrs *) ((unsigned char *) memory->data + buffer_length * memory_index); + memset(addrs, 0, sizeof(struct exynos_camera_addrs)); + addrs->type = 0; // kMetadataBufferTypeCameraSource + addrs->index = memory_index; + + exynos_camera_yuv_planes(width, height, format, memory_address, (int *) &addrs->y, (int *) &addrs->cbcr, NULL); + } else { + memory = output->memory; + memory_index = output->memory_index; + } + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_VIDEO_FRAME) && EXYNOS_CAMERA_CALLBACK_DEFINED(data_timestamp) && !exynos_camera->callback_lock) + exynos_camera->callbacks.data_timestamp(timestamp, CAMERA_MSG_VIDEO_FRAME, memory, memory_index, exynos_camera->callbacks.user); + else + exynos_camera_recording_frame_release(exynos_camera); + + if (exynos_camera->recording_metadata) { + memory_index++; + exynos_camera->recording_memory_index = memory_index % buffers_count; + } + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + exynos_camera->recording_listener->busy = 0; + + return rc; +} + +void *exynos_camera_recording_thread(void *data) +{ + struct exynos_camera *exynos_camera; + int rc; + + if (data == NULL) + return NULL; + + exynos_camera = (struct exynos_camera *) data; + + ALOGE("%s: Starting thread", __func__); + exynos_camera->recording_thread_running = 1; + + while (exynos_camera->recording_thread_enabled) { + pthread_mutex_lock(&exynos_camera->recording_lock_mutex); + + pthread_mutex_lock(&exynos_camera->recording_mutex); + + if (exynos_camera->recording_listener == NULL) { + pthread_mutex_unlock(&exynos_camera->recording_mutex); + break; + } + + if (exynos_camera->recording_listener->busy) { + rc = exynos_camera_recording(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to record", __func__); + pthread_mutex_unlock(&exynos_camera->recording_mutex); + break; + } + } + + pthread_mutex_unlock(&exynos_camera->recording_mutex); + } + + exynos_camera->recording_thread_running = 0; + ALOGE("%s: Exiting thread", __func__); + + return NULL; +} + +int exynos_camera_recording_thread_start(struct exynos_camera *exynos_camera) +{ + struct exynos_camera_capture_listener *listener; + pthread_attr_t thread_attr; + camera_memory_t *memory = NULL; + int buffer_length; + int buffers_count; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->recording_thread_enabled) { + ALOGE("Recording thread was already started!"); + return -1; + } + + pthread_mutex_init(&exynos_camera->recording_mutex, NULL); + pthread_mutex_init(&exynos_camera->recording_lock_mutex, NULL); + + // Initial lock + pthread_mutex_lock(&exynos_camera->recording_lock_mutex); + + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + + exynos_camera->recording_thread_enabled = 1; + + rc = pthread_create(&exynos_camera->recording_thread, &thread_attr, exynos_camera_recording_thread, (void *) exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to create thread", __func__); + goto error; + } + if (exynos_camera->recording_metadata) { + buffer_length = sizeof(struct exynos_camera_addrs); + buffers_count = EXYNOS_CAMERA_RECORDING_BUFFERS_COUNT; + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(-1, buffer_length, buffers_count, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + exynos_camera->recording_memory = memory; + exynos_camera->recording_buffer_length = buffer_length; + exynos_camera->recording_buffers_count = buffers_count; + } + + listener = exynos_camera_capture_listener_register(exynos_camera, exynos_camera->recording_width, exynos_camera->recording_height, exynos_camera->recording_format, exynos_camera_recording_callback); + if (listener == NULL) { + ALOGE("%s: Unable to register recording capture listener", __func__); + goto error; + } + + exynos_camera->recording_listener = listener; + + rc = 0; + goto complete; + +error: + if (memory != NULL && memory->release != NULL) { + memory->release(memory); + exynos_camera->recording_memory = NULL; + } + + pthread_mutex_destroy(&exynos_camera->recording_mutex); + pthread_mutex_destroy(&exynos_camera->recording_lock_mutex); + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_recording_thread_stop(struct exynos_camera *exynos_camera) +{ + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->recording_thread_enabled) { + ALOGE("Recording thread was already stopped!"); + return; + } + + if (exynos_camera->recording_listener != NULL) { + exynos_camera_capture_listener_unregister(exynos_camera, exynos_camera->recording_listener); + exynos_camera->recording_listener = NULL; + } + + exynos_camera->recording_thread_enabled = 0; + + pthread_mutex_unlock(&exynos_camera->recording_lock_mutex); + + // Wait for the thread to end + i = 0; + while (exynos_camera->recording_thread_running) { + if (i++ > 10000) { + ALOGE("Recording thread is taking too long to end, something is going wrong"); + break; + } + usleep(100); + } + + if (exynos_camera->recording_output_enabled) { + pthread_mutex_lock(&exynos_camera->recording_mutex); + exynos_camera_recording_output_stop(exynos_camera); + pthread_mutex_unlock(&exynos_camera->recording_mutex); + } + + pthread_mutex_destroy(&exynos_camera->recording_mutex); + pthread_mutex_destroy(&exynos_camera->recording_lock_mutex); +} + +// Auto-focus + +int exynos_camera_auto_focus(struct exynos_camera *exynos_camera, int auto_focus_status) +{ + if (exynos_camera == NULL) + return -EINVAL; + +// ALOGD("%s()", __func__); + + switch (auto_focus_status) { + case ISX012_AUTO_FOCUS_IN_PROGRESS: + case CAMERA_AF_STATUS_IN_PROGRESS: +/* + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS_MOVE) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_FOCUS_MOVE, 1, 0, exynos_camera->callbacks.user); +*/ + break; + + case CAMERA_AF_STATUS_SUCCESS: + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_FOCUS, 1, 0, exynos_camera->callbacks.user); + break; + + case CAMERA_AF_STATUS_FAIL: + default: + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_FOCUS, 0, 0, exynos_camera->callbacks.user); + break; + } + + return 0; +} + +void *exynos_camera_auto_focus_thread(void *data) +{ + struct exynos_camera *exynos_camera; + int auto_focus_status = CAMERA_AF_STATUS_FAIL; + int auto_focus_completed = 0; + int rc; + + if (data == NULL) + return NULL; + + exynos_camera = (struct exynos_camera *) data; + + ALOGE("%s: Starting thread", __func__); + exynos_camera->auto_focus_thread_running = 1; + + while (exynos_camera->auto_focus_thread_enabled) { + pthread_mutex_lock(&exynos_camera->auto_focus_mutex); + + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_AUTO_FOCUS_RESULT, &auto_focus_status); + if (rc < 0) { + ALOGE("%s: Unable to get auto-focus result", __func__); + auto_focus_status = CAMERA_AF_STATUS_FAIL; + } + + rc = exynos_camera_auto_focus(exynos_camera, auto_focus_status); + if (rc < 0) { + ALOGE("%s: Unable to auto-focus", __func__); + auto_focus_status = CAMERA_AF_STATUS_FAIL; + } + + if (auto_focus_status == ISX012_AUTO_FOCUS_IN_PROGRESS || auto_focus_status == CAMERA_AF_STATUS_IN_PROGRESS) + usleep(10000); + else + auto_focus_completed = 1; + + + pthread_mutex_unlock(&exynos_camera->auto_focus_mutex); + + if (auto_focus_completed) { + exynos_camera->auto_focus_thread_running = 0; + exynos_camera_auto_focus_thread_stop(exynos_camera); + } + } + + exynos_camera->auto_focus_thread_running = 0; + ALOGE("%s: Exiting thread", __func__); + + return NULL; +} + +int exynos_camera_auto_focus_thread_start(struct exynos_camera *exynos_camera) +{ + pthread_attr_t thread_attr; + int auto_focus; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->auto_focus_thread_enabled) { + ALOGE("Auto-focus thread was already started!"); + return -1; + } + + pthread_mutex_init(&exynos_camera->auto_focus_mutex, NULL); + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_ON); + if (rc < 0) { + ALOGE("%s: Unable to set auto-focus on", __func__); + goto error; + } + + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + + exynos_camera->auto_focus_thread_enabled = 1; + + rc = pthread_create(&exynos_camera->auto_focus_thread, &thread_attr, exynos_camera_auto_focus_thread, (void *) exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to create thread", __func__); + goto error; + } + + rc = 0; + goto complete; + +error: + pthread_mutex_destroy(&exynos_camera->auto_focus_mutex); + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_auto_focus_thread_stop(struct exynos_camera *exynos_camera) +{ + int rc; + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->auto_focus_thread_enabled) { + ALOGE("Auto-focus thread was already stopped!"); + return; + } + + exynos_camera->auto_focus_thread_enabled = 0; + + // Wait for the thread to end + i = 0; + while (exynos_camera->auto_focus_thread_running) { + if (i++ > 10000) { + ALOGE("Auto-focus thread is taking too long to end, something is going wrong"); + break; + } + usleep(100); + } + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_OFF); + if (rc < 0) + ALOGE("%s: Unable to set auto-focus off", __func__); + + pthread_mutex_destroy(&exynos_camera->auto_focus_mutex); +} + +/* + * Exynos Camera OPS + */ + +int exynos_camera_set_preview_window(struct camera_device *dev, + struct preview_stream_ops *w) +{ + struct exynos_camera *exynos_camera; + + int width, height, format, gralloc_format; + + buffer_handle_t *buffer; + int stride; + void *addr = NULL; + + int rc; + + ALOGD("%s(%p, %p)", __func__, dev, w); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + if (exynos_camera->preview_thread_enabled) + pthread_mutex_lock(&exynos_camera->preview_mutex); + + if (w == NULL) { + exynos_camera->preview_window = NULL; + return 0; + } + + if (w->set_buffer_count == NULL || w->set_usage == NULL || w->set_buffers_geometry == NULL) + goto error; + + rc = w->set_buffer_count(w, EXYNOS_CAMERA_GRALLOC_BUFFERS_COUNT); + if (rc) { + ALOGE("%s: Unable to set buffer count: %d", __func__, EXYNOS_CAMERA_GRALLOC_BUFFERS_COUNT); + goto error; + } + + rc = w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN); + if (rc) { + ALOGE("%s: Unable to set usage", __func__); + goto error; + } + + width = exynos_camera->preview_width; + height = exynos_camera->preview_height; + format = exynos_camera->preview_format; + + switch (format) { + case V4L2_PIX_FMT_NV21: + gralloc_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; + break; + case V4L2_PIX_FMT_YUV420: + gralloc_format = HAL_PIXEL_FORMAT_YV12; + break; + case V4L2_PIX_FMT_RGB565: + gralloc_format = HAL_PIXEL_FORMAT_RGB_565; + break; + case V4L2_PIX_FMT_RGB32: + gralloc_format = HAL_PIXEL_FORMAT_RGBX_8888; + break; + default: + gralloc_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; + break; + } + + rc = w->set_buffers_geometry(w, width, height, gralloc_format); + if (rc) { + ALOGE("%s: Unable to set buffers geometry", __func__); + goto error; + } + + exynos_camera->preview_window = w; + + rc = 0; + goto complete; + +error: + exynos_camera->preview_window = NULL; + rc = -1; + +complete: + if (exynos_camera->preview_thread_enabled) + pthread_mutex_unlock(&exynos_camera->preview_mutex); + + return rc; +} + +void exynos_camera_set_callbacks(struct camera_device *dev, + camera_notify_callback notify_cb, + camera_data_callback data_cb, + camera_data_timestamp_callback data_cb_timestamp, + camera_request_memory get_memory, + void *user) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p, %p)", __func__, dev, user); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callbacks.notify = notify_cb; + exynos_camera->callbacks.data = data_cb; + exynos_camera->callbacks.data_timestamp = data_cb_timestamp; + exynos_camera->callbacks.request_memory = get_memory; + exynos_camera->callbacks.user = user; +} + +void exynos_camera_enable_msg_type(struct camera_device *dev, int32_t msg_type) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p, %d)", __func__, dev, msg_type); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->messages_enabled |= msg_type; +} + +void exynos_camera_disable_msg_type(struct camera_device *dev, int32_t msg_type) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p, %d)", __func__, dev, msg_type); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->messages_enabled &= ~msg_type; +} + +int exynos_camera_msg_type_enabled(struct camera_device *dev, int32_t msg_type) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p, %d)", __func__, dev, msg_type); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + return exynos_camera->messages_enabled & msg_type; +} + +int exynos_camera_start_preview(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + int rc; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + rc = exynos_camera_preview_thread_start(exynos_camera); + exynos_camera->callback_lock = 0; + + return rc; +} + +void exynos_camera_stop_preview(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + exynos_camera_preview_thread_stop(exynos_camera); + exynos_camera->callback_lock = 0; +} + +int exynos_camera_preview_enabled(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + return exynos_camera->preview_thread_enabled; +} + +int exynos_camera_store_meta_data_in_buffers(struct camera_device *dev, + int enable) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p, %d)", __func__, dev, enable); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + if (!exynos_camera->recording_thread_enabled) + exynos_camera->recording_metadata = enable; + else + ALOGE("%s: Recording is running!", __func__); + + return 0; +} + +int exynos_camera_start_recording(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + int rc; + + ALOGD("%s(%p)", __func__, dev); + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + rc = exynos_camera_recording_thread_start(exynos_camera); + exynos_camera->callback_lock = 0; + + return rc; +} + +void exynos_camera_stop_recording(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + exynos_camera_recording_thread_stop(exynos_camera); + exynos_camera->callback_lock = 0; +} + +int exynos_camera_recording_enabled(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + return exynos_camera->recording_thread_enabled; +} + +void exynos_camera_release_recording_frame(struct camera_device *dev, + const void *opaque) +{ + struct exynos_camera *exynos_camera; + +// ALOGD("%s(%p, %p)", __func__, dev, opaque); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera_recording_frame_release(exynos_camera); +} + +int exynos_camera_start_auto_focus(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + return exynos_camera_auto_focus_thread_start(exynos_camera); +} + +int exynos_camera_cancel_auto_focus(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera_auto_focus_thread_stop(exynos_camera); + + return 0; +} + +int exynos_camera_take_picture(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + int rc; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + if (exynos_camera->picture_thread_running + || exynos_camera->auto_focus_thread_enabled) + { + return 0; + } + + exynos_camera->callback_lock = 1; + rc = exynos_camera_picture_thread_start(exynos_camera); + exynos_camera->callback_lock = 0; + + return rc; +} + +int exynos_camera_cancel_picture(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + int rc; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + exynos_camera_picture_thread_stop(exynos_camera); + exynos_camera->callback_lock = 0; + + return 0; +} + +int exynos_camera_set_parameters(struct camera_device *dev, + const char *params) +{ + struct exynos_camera *exynos_camera; + int rc; + + ALOGD("%s(%p, %s)", __func__, dev, params); + + if (dev == NULL || dev->priv == NULL || params == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + rc = exynos_params_string_set(exynos_camera, (char *) params); + if (rc < 0) { + ALOGE("%s: Unable to set params string", __func__); + return -1; + } + + rc = exynos_camera_params_apply(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s: Unable to apply params", __func__); + return -1; + } + + return 0; +} + +char *exynos_camera_get_parameters(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + char *params; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return NULL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + params = exynos_params_string_get(exynos_camera); + if (params == NULL) { + ALOGE("%s: Couldn't find any param", __func__); + return strdup(""); + } + + return params; +} + +void exynos_camera_put_parameters(struct camera_device *dev, char *params) +{ + ALOGD("%s(%p)", __func__, dev); + + if (params != NULL) + free(params); +} + +int exynos_camera_send_command(struct camera_device *dev, + int32_t cmd, int32_t arg1, int32_t arg2) +{ + ALOGD("%s(%p, %d, %d, %d)", __func__, dev, cmd, arg1, arg2); + + return 0; +} + +void exynos_camera_release(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera_capture_thread_stop(exynos_camera); + + exynos_camera_stop(exynos_camera); +} + +int exynos_camera_dump(struct camera_device *dev, int fd) +{ + ALOGD("%s(%p, %d)", __func__, dev, fd); + + return 0; +} + +/* + * Interface + */ + +struct camera_device_ops exynos_camera_ops = { + .set_preview_window = exynos_camera_set_preview_window, + .set_callbacks = exynos_camera_set_callbacks, + .enable_msg_type = exynos_camera_enable_msg_type, + .disable_msg_type = exynos_camera_disable_msg_type, + .msg_type_enabled = exynos_camera_msg_type_enabled, + .start_preview = exynos_camera_start_preview, + .stop_preview = exynos_camera_stop_preview, + .preview_enabled = exynos_camera_preview_enabled, + .store_meta_data_in_buffers = exynos_camera_store_meta_data_in_buffers, + .start_recording = exynos_camera_start_recording, + .stop_recording = exynos_camera_stop_recording, + .recording_enabled = exynos_camera_recording_enabled, + .release_recording_frame = exynos_camera_release_recording_frame, + .auto_focus = exynos_camera_start_auto_focus, + .cancel_auto_focus = exynos_camera_cancel_auto_focus, + .take_picture = exynos_camera_take_picture, + .cancel_picture = exynos_camera_cancel_picture, + .set_parameters = exynos_camera_set_parameters, + .get_parameters = exynos_camera_get_parameters, + .put_parameters = exynos_camera_put_parameters, + .send_command = exynos_camera_send_command, + .release = exynos_camera_release, + .dump = exynos_camera_dump, +}; + +int exynos_camera_close(hw_device_t *device) +{ + struct camera_device *camera_device; + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, device); + + if (device == NULL) + return -EINVAL; + + camera_device = (struct camera_device *) device; + + if (camera_device->priv != NULL) { + free(camera_device->priv); + } + + free(camera_device); + + return 0; +} + +int exynos_camera_open(const struct hw_module_t* module, const char *camera_id, + struct hw_device_t** device) +{ + struct camera_device *camera_device = NULL; + struct exynos_camera *exynos_camera = NULL; + int id; + int rc; + + ALOGD("%s(%p, %s, %p)", __func__, module, camera_id, device); + + if (module == NULL || camera_id == NULL || device == NULL) + return -EINVAL; + + id = atoi(camera_id); + if (id < 0) + return -EINVAL; + + exynos_camera = calloc(1, sizeof(struct exynos_camera)); + exynos_camera->config = exynos_camera_config; + + if (exynos_camera->config->v4l2_nodes_count > EXYNOS_CAMERA_MAX_V4L2_NODES_COUNT) + goto error_preset; + + if (id >= exynos_camera->config->presets_count) + goto error_preset; + + rc = exynos_camera_start(exynos_camera, id); + if (rc < 0) { + ALOGE("%s: Unable to start camera", __func__); + goto error; + } + + rc = exynos_camera_capture_thread_start(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to start capture thread", __func__); + goto error; + } + + camera_device = calloc(1, sizeof(struct camera_device)); + camera_device->common.tag = HARDWARE_DEVICE_TAG; + camera_device->common.version = 0; + camera_device->common.module = (struct hw_module_t *) module; + camera_device->common.close = exynos_camera_close; + + camera_device->ops = &exynos_camera_ops; + camera_device->priv = exynos_camera; + + *device = (struct hw_device_t *) &(camera_device->common); + + return 0; + +error: + exynos_camera_stop(exynos_camera); + +error_device: + if (camera_device != NULL) + free(camera_device); + +error_preset: + if (exynos_camera != NULL) + free(exynos_camera); + + return -1; +} + +int exynos_camera_get_number_of_cameras(void) +{ + ALOGD("%s()", __func__); + + if (exynos_camera_config == NULL || exynos_camera_config->presets == NULL) { + ALOGE("%s: Unable to find proper camera config", __func__); + return -1; + } + + return exynos_camera_config->presets_count; +} + +int exynos_camera_get_camera_info(int id, struct camera_info *info) +{ + ALOGD("%s(%d, %p)", __func__, id, info); + + if (id < 0 || info == NULL) + return -EINVAL; + + if (exynos_camera_config == NULL || exynos_camera_config->presets == NULL) { + ALOGE("%s: Unable to find proper camera config", __func__); + return -1; + } + + if (id >= exynos_camera_config->presets_count) + return -EINVAL; + + ALOGD("Selected camera: %s", exynos_camera_config->presets[id].name); + + info->facing = exynos_camera_config->presets[id].facing; + info->orientation = exynos_camera_config->presets[id].orientation; + + return 0; +} + +struct hw_module_methods_t exynos_camera_module_methods = { + .open = exynos_camera_open, +}; + +struct camera_module HAL_MODULE_INFO_SYM = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .hal_api_version = HARDWARE_HAL_API_VERSION, + .module_api_version = CAMERA_MODULE_API_VERSION_1_0, + .id = CAMERA_HARDWARE_MODULE_ID, + .name = "Exynos Camera", + .author = "Paul Kocialkowski", + .methods = &exynos_camera_module_methods, + }, + .get_number_of_cameras = exynos_camera_get_number_of_cameras, + .get_camera_info = exynos_camera_get_camera_info, +}; diff --git a/camera/exynos_camera.h b/camera/exynos_camera.h new file mode 100755 index 0000000..fe7459c --- /dev/null +++ b/camera/exynos_camera.h @@ -0,0 +1,680 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef EXYNOS_JPEG_HW +#include +#endif +#include + +#include +#include + +#ifndef _EXYNOS_CAMERA_H_ +#define _EXYNOS_CAMERA_H_ + +#define EXYNOS_CAMERA_MAX_V4L2_NODES_COUNT 4 + +#define EXYNOS_CAMERA_CAPTURE_BUFFERS_COUNT 1 +#define EXYNOS_CAMERA_PREVIEW_BUFFERS_COUNT 8 +#define EXYNOS_CAMERA_RECORDING_BUFFERS_COUNT 6 +#define EXYNOS_CAMERA_GRALLOC_BUFFERS_COUNT 3 + +#define EXYNOS_CAMERA_UNKNOWN_CAPTURE_MODE 167774080 +#define ISX012_AUTO_FOCUS_IN_PROGRESS 0x8 + +#define EXYNOS_CAMERA_PICTURE_OUTPUT_FORMAT V4L2_PIX_FMT_YUYV + +#define EXYNOS_CAMERA_MSG_ENABLED(msg) (exynos_camera->messages_enabled & msg) +#define EXYNOS_CAMERA_CALLBACK_DEFINED(cb) (exynos_camera->callbacks.cb != NULL) + +#define EXYNOS_CAMERA_ALIGN(value) ((value + (0x10000 - 1)) & ~(0x10000 - 1)) + +/* + * Structures + */ + +struct exynos_camera; + +struct list_head { + struct list_head *next; + struct list_head *prev; +}; + +enum exynos_param_type { + EXYNOS_PARAM_INT, + EXYNOS_PARAM_FLOAT, + EXYNOS_PARAM_STRING, +}; + +union exynos_param_data { + int integer; + float floating; + char *string; +}; + +struct exynos_param { + struct list_head list; + + char *key; + union exynos_param_data data; + enum exynos_param_type type; +}; + +struct exynos_camera_buffer { + void *pointer; + int address; + int length; + + int width; + int height; + int format; +}; + +struct exynos_camera_capture_listener { + struct list_head list; + + int width; + int height; + int format; + + int (*callback)(struct exynos_camera *exynos_camera, struct exynos_camera_buffer *buffers, int buffers_count); + int busy; +}; + +struct exynos_camera_mbus_resolution { + int width; + int height; + int mbus_width; + int mbus_height; +}; + +struct exynos_camera_params { + char *preview_size_values; + char *preview_size; + char *preview_format_values; + char *preview_format; + char *preview_frame_rate_values; + int preview_frame_rate; + char *preview_fps_range_values; + char *preview_fps_range; + + char *picture_size_values; + char *picture_size; + char *picture_format_values; + char *picture_format; + char *jpeg_thumbnail_size_values; + int jpeg_thumbnail_width; + int jpeg_thumbnail_height; + int jpeg_thumbnail_quality; + int jpeg_quality; + + int video_snapshot_supported; + int full_video_snap_supported; + + char *recording_size; + char *recording_size_values; + char *recording_format; + + char *focus_mode; + char *focus_mode_values; + char *focus_distances; + char *focus_areas; + int max_num_focus_areas; + + int zoom_supported; + int smooth_zoom_supported; + char *zoom_ratios; + int zoom; + int max_zoom; + + char *flash_mode; + char *flash_mode_values; + + int exposure_compensation; + float exposure_compensation_step; + int min_exposure_compensation; + int max_exposure_compensation; + + char *whitebalance; + char *whitebalance_values; + + char *antibanding; + char *antibanding_values; + + char *scene_mode; + char *scene_mode_values; + + char *effect; + char *effect_values; + + char *iso; + char *iso_values; +}; + +struct exynos_camera_preset { + char *name; + int facing; + int orientation; + + int rotation; + int hflip; + int vflip; + + int capture_format; + int picture_format; + int fimc_is; + + float focal_length; + float horizontal_view_angle; + float vertical_view_angle; + + int metering; + + struct exynos_camera_params params; + struct exynos_camera_mbus_resolution *mbus_resolutions; + int mbus_resolutions_count; +}; + +struct exynos_v4l2_node { + int id; + char *node; +}; + +struct exynos_v4l2_output { + int enabled; + + int v4l2_id; + + int width; + int height; + int format; + + int buffer_width; + int buffer_height; + int buffer_format; + + camera_memory_t *memory; + int memory_address; +#ifdef EXYNOS_ION + int memory_ion_fd; +#endif + int memory_index; + int buffers_count; + int buffer_length; +}; + +struct exynos_exif { + int enabled; + + exif_attribute_t attributes; + void *jpeg_thumbnail_data; + int jpeg_thumbnail_size; + + camera_memory_t *memory; + int memory_size; +}; + +#ifdef EXYNOS_JPEG_HW +struct exynos_jpeg { + int enabled; + + int fd; + struct jpeg_buf buffer_in; + struct jpeg_buf buffer_out; + camera_memory_t *memory_in; + void *memory_in_pointer; +#ifdef EXYNOS_ION + int memory_in_ion_fd; +#endif + camera_memory_t *memory_out; + void *memory_out_pointer; + int memory_out_size; +#ifdef EXYNOS_ION + int memory_out_ion_fd; +#endif + + int width; + int height; + int format; + + int quality; +}; +#endif + +struct exynox_camera_config { + struct exynos_camera_preset *presets; + int presets_count; + + struct exynos_v4l2_node *v4l2_nodes; + int v4l2_nodes_count; +}; + +struct exynos_camera_callbacks { + camera_notify_callback notify; + camera_data_callback data; + camera_data_timestamp_callback data_timestamp; + camera_request_memory request_memory; + void *user; +}; + +struct exynos_camera { + int v4l2_fds[EXYNOS_CAMERA_MAX_V4L2_NODES_COUNT]; + int ion_fd; + + struct exynox_camera_config *config; + struct exynos_param *params; + + struct exynos_camera_callbacks callbacks; + int callback_lock; + int messages_enabled; + + gralloc_module_t *gralloc; + + // Capture + + pthread_t capture_thread; + pthread_mutex_t capture_mutex; + pthread_mutex_t capture_lock_mutex; + int capture_thread_running; + int capture_thread_enabled; + + int capture_enabled; + struct exynos_camera_capture_listener *capture_listeners; + camera_memory_t *capture_memory; + int capture_memory_address; + int capture_memory_index; + void *capture_yuv_buffer; + void *capture_jpeg_buffer; + int capture_auto_focus_result; + int capture_hybrid; + int capture_width; + int capture_height; + int capture_format; + int capture_buffers_count; + int capture_buffer_length; + + // Preview + + pthread_t preview_thread; + pthread_mutex_t preview_mutex; + pthread_mutex_t preview_lock_mutex; + int preview_thread_running; + int preview_thread_enabled; + + int preview_output_enabled; + struct exynos_camera_capture_listener *preview_listener; + struct preview_stream_ops *preview_window; + struct exynos_camera_buffer preview_buffer; + struct exynos_v4l2_output preview_output; + + // Picture + + pthread_t picture_thread; + pthread_mutex_t picture_mutex; + pthread_mutex_t picture_lock_mutex; + int picture_thread_running; + int picture_thread_enabled; + + int picture_enabled; + int picture_completed; + struct exynos_camera_capture_listener *picture_listener; + camera_memory_t *picture_memory; + struct exynos_camera_buffer picture_jpeg_buffer; + struct exynos_camera_buffer picture_jpeg_thumbnail_buffer; + struct exynos_camera_buffer picture_yuv_buffer; + struct exynos_camera_buffer picture_yuv_thumbnail_buffer; + + // Recording + + pthread_t recording_thread; + pthread_mutex_t recording_mutex; + pthread_mutex_t recording_lock_mutex; + int recording_thread_running; + int recording_thread_enabled; + + int recording_output_enabled; + struct exynos_camera_capture_listener *recording_listener; + camera_memory_t *recording_memory; + int recording_memory_index; + struct exynos_camera_buffer recording_buffer; + struct exynos_v4l2_output recording_output; + int recording_buffers_count; + int recording_buffer_length; + int recording_metadata; + + // Auto-focus + + pthread_t auto_focus_thread; + pthread_mutex_t auto_focus_mutex; + int auto_focus_thread_enabled; + int auto_focus_thread_running; + + // Camera params + + int camera_rotation; + int camera_hflip; + int camera_vflip; + int camera_capture_format; + int camera_picture_format; + int camera_fimc_is; + int camera_focal_length; + int camera_metering; + + struct exynos_camera_mbus_resolution *camera_mbus_resolutions; + int camera_mbus_resolutions_count; + + int camera_sensor_mode; + int fimc_is_mode; + + // Params + + int preview_width; + int preview_height; + int preview_format; + int preview_fps; + int picture_width; + int picture_height; + int picture_format; + int jpeg_thumbnail_width; + int jpeg_thumbnail_height; + int jpeg_thumbnail_quality; + int jpeg_quality; + int recording_width; + int recording_height; + int recording_format; + int focus_mode; + int focus_x; + int focus_y; + int zoom; + int flash_mode; + int exposure_compensation; + int whitebalance; + int antibanding; + int scene_mode; + int effect; + int iso; + int metering; +}; + +struct exynos_camera_addrs { + unsigned int type; + unsigned int y; + unsigned int cbcr; + unsigned int index; + unsigned int reserved; +}; + +// This is because the linux header uses anonymous union +struct exynos_v4l2_ext_control { + __u32 id; + __u32 size; + __u32 reserved2[1]; + union { + __s32 value; + __s64 value64; + char *string; + } data; +} __attribute__ ((packed)); + +/* + * Camera + */ + +// Camera +int exynos_camera_start(struct exynos_camera *exynos_camera, int id); +void exynos_camera_stop(struct exynos_camera *exynos_camera); + +// Params +int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id); +int exynos_camera_params_apply(struct exynos_camera *exynos_camera, int force); + +// Capture +int exynos_camera_capture(struct exynos_camera *exynos_camera); +int exynos_camera_capture_thread_start(struct exynos_camera *exynos_camera); +void exynos_camera_capture_thread_stop(struct exynos_camera *exynos_camera); +int exynos_camera_capture_start(struct exynos_camera *exynos_camera, int is_capture); +void exynos_camera_capture_stop(struct exynos_camera *exynos_camera); +int exynos_camera_capture_setup(struct exynos_camera *exynos_camera); +struct exynos_camera_capture_listener *exynos_camera_capture_listener_register( + struct exynos_camera *exynos_camera, int width, int height, int format, + int (*callback)(struct exynos_camera *exynos_camera, struct exynos_camera_buffer *buffers, int buffers_count)); +void exynos_camera_capture_listener_unregister( + struct exynos_camera *exynos_camera, + struct exynos_camera_capture_listener *listener); + +// Preview +int exynos_camera_preview_output_start(struct exynos_camera *exynos_camera); +void exynos_camera_preview_output_stop(struct exynos_camera *exynos_camera); +int exynos_camera_preview_callback(struct exynos_camera *exynos_camera, + struct exynos_camera_buffer *buffers, int buffers_count); +int exynos_camera_preview(struct exynos_camera *exynos_camera); +int exynos_camera_preview_thread_start(struct exynos_camera *exynos_camera); +void exynos_camera_preview_thread_stop(struct exynos_camera *exynos_camera); + +// Picture +int exynos_camera_picture_callback(struct exynos_camera *exynos_camera, + struct exynos_camera_buffer *buffers, int buffers_count); +int exynos_camera_picture(struct exynos_camera *exynos_camera); +int exynos_camera_picture_thread_start(struct exynos_camera *exynos_camera); +void exynos_camera_picture_thread_stop(struct exynos_camera *exynos_camera); + +// Recording +int exynos_camera_recording_output_start(struct exynos_camera *exynos_camera); +void exynos_camera_recording_output_stop(struct exynos_camera *exynos_camera); +int exynos_camera_recording_callback(struct exynos_camera *exynos_camera, + struct exynos_camera_buffer *buffers, int buffers_count); +void exynos_camera_recording_frame_release(struct exynos_camera *exynos_camera); +int exynos_camera_recording(struct exynos_camera *exynos_camera); +int exynos_camera_recording_thread_start(struct exynos_camera *exynos_camera); +void exynos_camera_recording_thread_stop(struct exynos_camera *exynos_camera); + +// Auto-focus +int exynos_camera_auto_focus(struct exynos_camera *exynos_camera, int auto_focus_status); +int exynos_camera_auto_focus_thread_start(struct exynos_camera *exynos_camera); +void exynos_camera_auto_focus_thread_stop(struct exynos_camera *exynos_camera); + +/* + * EXIF + */ + +int exynos_exif_start(struct exynos_camera *exynos_camera, struct exynos_exif *exif); +void exynos_exif_stop(struct exynos_camera *exynos_camera, + struct exynos_exif *exif); +int exynos_exif(struct exynos_camera *exynos_camera, struct exynos_exif *exif); + +/* + * ION + */ + +#ifdef EXYNOS_ION +int exynos_ion_init(struct exynos_camera *exynos_camera); +int exynos_ion_open(struct exynos_camera *exynos_camera); +void exynos_ion_close(struct exynos_camera *exynos_camera); +int exynos_ion_alloc(struct exynos_camera *exynos_camera, int size); +int exynos_ion_free(struct exynos_camera *exynos_camera, int fd); +int exynos_ion_phys(struct exynos_camera *exynos_camera, int fd); +int exynos_ion_msync(struct exynos_camera *exynos_camera, int fd, + int offset, int size); +#endif + +/* + * Jpeg + */ + +int exynos_jpeg_start(struct exynos_camera *exynos_camera, + struct exynos_jpeg *jpeg); +void exynos_jpeg_stop(struct exynos_camera *exynos_camera, + struct exynos_jpeg *jpeg); +int exynos_jpeg(struct exynos_camera *exynos_camera, struct exynos_jpeg *jpeg); + +/* + * Param + */ + +int exynos_param_int_get(struct exynos_camera *exynos_camera, + char *key); +float exynos_param_float_get(struct exynos_camera *exynos_camera, + char *key); +char *exynos_param_string_get(struct exynos_camera *exynos_camera, + char *key); +int exynos_param_int_set(struct exynos_camera *exynos_camera, + char *key, int integer); +int exynos_param_float_set(struct exynos_camera *exynos_camera, + char *key, float floating); +int exynos_param_string_set(struct exynos_camera *exynos_camera, + char *key, char *string); +char *exynos_params_string_get(struct exynos_camera *exynos_camera); +int exynos_params_string_set(struct exynos_camera *exynos_camera, char *string); + +/* + * Utils + */ + +int list_head_insert(struct list_head *list, struct list_head *prev, + struct list_head *next); +void list_head_remove(struct list_head *list); + +int exynos_camera_buffer_length(int width, int height, int format); +void exynos_camera_yuv_planes(int width, int height, int format, int address, int *address_y, int *address_cb, int *address_cr); + +/* + * V4L2 + */ + +int exynos_v4l2_init(struct exynos_camera *exynos_camera); +int exynos_v4l2_index(struct exynos_camera *exynos_camera, int exynos_v4l2_id); +int exynos_v4l2_fd(struct exynos_camera *exynos_camera, int exynos_v4l2_id); + +int exynos_v4l2_open(struct exynos_camera *exynos_camera, int exynos_v4l2_id); +void exynos_v4l2_close(struct exynos_camera *exynos_camera, int exynos_v4l2_id); +int exynos_v4l2_ioctl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int request, void *data); +int exynos_v4l2_poll(struct exynos_camera *exynos_camera, int exynos_v4l2_id); +int exynos_v4l2_qbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int memory, int index, unsigned long userptr); +int exynos_v4l2_qbuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int index); +int exynos_v4l2_qbuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int index, unsigned long userptr); +int exynos_v4l2_dqbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int memory); +int exynos_v4l2_dqbuf_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_dqbuf_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_reqbufs(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int memory, int count); +int exynos_v4l2_reqbufs_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int count); +int exynos_v4l2_reqbufs_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int count); +int exynos_v4l2_querybuf(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int memory, int index); +int exynos_v4l2_querybuf_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int index); +int exynos_v4l2_querybuf_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int index); +int exynos_v4l2_querycap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int flags); +int exynos_v4l2_querycap_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_querycap_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_streamon(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type); +int exynos_v4l2_streamon_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_streamon_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_streamoff(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type); +int exynos_v4l2_streamoff_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_streamoff_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_g_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int *width, int *height, int *fmt); +int exynos_v4l2_g_fmt_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int *width, int *height, int *fmt); +int exynos_v4l2_g_fmt_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int *width, int *height, int *fmt); +int exynos_v4l2_s_fmt_pix(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int width, int height, int fmt, int field, + int priv); +int exynos_v4l2_s_fmt_pix_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int width, int height, int fmt, int priv); +int exynos_v4l2_s_fmt_pix_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int width, int height, int fmt, int priv); +int exynos_v4l2_s_fmt_win(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height); +int exynos_v4l2_enum_fmt(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int fmt); +int exynos_v4l2_enum_fmt_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int fmt); +int exynos_v4l2_enum_fmt_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int fmt); +int exynos_v4l2_enum_input(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int id); +int exynos_v4l2_s_input(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id); +int exynos_v4l2_g_ext_ctrls(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_ext_control *control, int count); +int exynos_v4l2_g_ctrl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id, int *value); +int exynos_v4l2_s_ctrl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id, int value); +int exynos_v4l2_s_parm(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, struct v4l2_streamparm *streamparm); +int exynos_v4l2_s_parm_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_streamparm *streamparm); +int exynos_v4l2_s_parm_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_streamparm *streamparm); +int exynos_v4l2_s_crop(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int left, int top, int width, int height); +int exynos_v4l2_s_crop_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height); +int exynos_v4l2_s_crop_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height); +int exynos_v4l2_g_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + void **base, int *width, int *height, int *fmt); +int exynos_v4l2_s_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + void *base, int width, int height, int fmt); + +/* + * V4L2 Output + */ + +int exynos_v4l2_output_start(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output); +void exynos_v4l2_output_stop(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output); +int exynos_v4l2_output(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output, int buffer_address); +int exynos_v4l2_output_release(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output); + +#endif diff --git a/camera/exynos_exif.c b/camera/exynos_exif.c new file mode 100644 index 0000000..2ba4ca1 --- /dev/null +++ b/camera/exynos_exif.c @@ -0,0 +1,873 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * Based on crespo libcamera and exynos4 hal libcamera: + * Copyright 2008, The Android Open Source Project + * Copyright 2010, Samsung Electronics Co. LTD + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define LOG_TAG "exynos_camera" +#include +#include + +#include "exynos_camera.h" + +int exynos_exif_attributes_create_static(struct exynos_camera *exynos_camera, + struct exynos_exif *exif) +{ + exif_attribute_t *attributes; + unsigned char gps_version[] = { 0x02, 0x02, 0x00, 0x00 }; + char property[PROPERTY_VALUE_MAX]; + uint32_t av; + + if (exynos_camera == NULL || exif == NULL) + return -EINVAL; + + attributes = &exif->attributes; + + // Device + + property_get("ro.product.brand", property, EXIF_DEF_MAKER); + strncpy((char *) attributes->maker, property, + sizeof(attributes->maker) - 1); + attributes->maker[sizeof(attributes->maker) - 1] = '\0'; + + property_get("ro.product.model", property, EXIF_DEF_MODEL); + strncpy((char *) attributes->model, property, + sizeof(attributes->model) - 1); + attributes->model[sizeof(attributes->model) - 1] = '\0'; + + property_get("ro.build.id", property, EXIF_DEF_SOFTWARE); + strncpy((char *) attributes->software, property, + sizeof(attributes->software) - 1); + attributes->software[sizeof(attributes->software) - 1] = '\0'; + + attributes->ycbcr_positioning = EXIF_DEF_YCBCR_POSITIONING; + + attributes->fnumber.num = EXIF_DEF_FNUMBER_NUM; + attributes->fnumber.den = EXIF_DEF_FNUMBER_DEN; + + attributes->exposure_program = EXIF_DEF_EXPOSURE_PROGRAM; + + memcpy(attributes->exif_version, EXIF_DEF_EXIF_VERSION, + sizeof(attributes->exif_version)); + + av = APEX_FNUM_TO_APERTURE((double) attributes->fnumber.num / + attributes->fnumber.den); + attributes->aperture.num = av; + attributes->aperture.den = EXIF_DEF_APEX_DEN; + attributes->max_aperture.num = av; + attributes->max_aperture.den = EXIF_DEF_APEX_DEN; + + strcpy((char *) attributes->user_comment, EXIF_DEF_USERCOMMENTS); + attributes->color_space = EXIF_DEF_COLOR_SPACE; + attributes->exposure_mode = EXIF_DEF_EXPOSURE_MODE; + + // GPS version + + memcpy(attributes->gps_version_id, gps_version, sizeof(gps_version)); + + attributes->compression_scheme = EXIF_DEF_COMPRESSION; + attributes->x_resolution.num = EXIF_DEF_RESOLUTION_NUM; + attributes->x_resolution.den = EXIF_DEF_RESOLUTION_DEN; + attributes->y_resolution.num = EXIF_DEF_RESOLUTION_NUM; + attributes->y_resolution.den = EXIF_DEF_RESOLUTION_DEN; + attributes->resolution_unit = EXIF_DEF_RESOLUTION_UNIT; + + return 0; +} + +int exynos_exif_attributes_create_gps(struct exynos_camera *exynos_camera, + struct exynos_exif *exif) +{ + exif_attribute_t *attributes; + float gps_latitude_float, gps_longitude_float, gps_altitude_float; + int gps_timestamp_int; + char *gps_processing_method_string; + long gps_latitude, gps_longitude; + long gps_altitude, gps_timestamp; + double gps_latitude_abs, gps_longitude_abs, gps_altitude_abs; + + struct tm time_info; + + if (exynos_camera == NULL || exif == NULL) + return -EINVAL; + + attributes = &exif->attributes; + + gps_latitude_float = exynos_param_float_get(exynos_camera, "gps-latitude"); + gps_longitude_float = exynos_param_float_get(exynos_camera, "gps-longitude"); + gps_altitude_float = exynos_param_float_get(exynos_camera, "gps-altitude"); + if (gps_altitude_float == -1) + gps_altitude_float = (float) exynos_param_int_get(exynos_camera, "gps-altitude"); + gps_timestamp_int = exynos_param_int_get(exynos_camera, "gps-timestamp"); + gps_processing_method_string = exynos_param_string_get(exynos_camera, "gps-processing-method"); + + if (gps_latitude_float == -1 || gps_longitude_float == -1 || + gps_altitude_float == -1 || gps_timestamp_int <= 0 || + gps_processing_method_string == NULL) { + attributes->enableGps = false; + return 0; + } + + gps_latitude = (long) (gps_latitude_float * 10000000) / 1; + gps_longitude = (long) (gps_longitude_float * 10000000) / 1; + gps_altitude = (long) (gps_altitude_float * 100) / 1; + gps_timestamp = (long) gps_timestamp_int; + + if (gps_latitude == 0 || gps_longitude == 0) { + attributes->enableGps = false; + return 0; + } + + if (gps_latitude > 0) + strcpy((char *) attributes->gps_latitude_ref, "N"); + else + strcpy((char *) attributes->gps_latitude_ref, "S"); + + if (gps_longitude > 0) + strcpy((char *) attributes->gps_longitude_ref, "E"); + else + strcpy((char *) attributes->gps_longitude_ref, "W"); + + if (gps_altitude > 0) + attributes->gps_altitude_ref = 0; + else + attributes->gps_altitude_ref = 1; + + + gps_latitude_abs = fabs(gps_latitude); + gps_longitude_abs = fabs(gps_longitude); + gps_altitude_abs = fabs(gps_altitude); + + attributes->gps_latitude[0].num = (uint32_t) gps_latitude_abs; + attributes->gps_latitude[0].den = 10000000; + attributes->gps_latitude[1].num = 0; + attributes->gps_latitude[1].den = 1; + attributes->gps_latitude[2].num = 0; + attributes->gps_latitude[2].den = 1; + + attributes->gps_longitude[0].num = (uint32_t) gps_longitude_abs; + attributes->gps_longitude[0].den = 10000000; + attributes->gps_longitude[1].num = 0; + attributes->gps_longitude[1].den = 1; + attributes->gps_longitude[2].num = 0; + attributes->gps_longitude[2].den = 1; + + attributes->gps_altitude.num = (uint32_t) gps_altitude_abs; + attributes->gps_altitude.den = 100; + + gmtime_r(&gps_timestamp, &time_info); + + attributes->gps_timestamp[0].num = time_info.tm_hour; + attributes->gps_timestamp[0].den = 1; + attributes->gps_timestamp[1].num = time_info.tm_min; + attributes->gps_timestamp[1].den = 1; + attributes->gps_timestamp[2].num = time_info.tm_sec; + attributes->gps_timestamp[2].den = 1; + snprintf((char *) attributes->gps_datestamp, sizeof(attributes->gps_datestamp), + "%04d:%02d:%02d", time_info.tm_year + 1900, time_info.tm_mon + 1, time_info.tm_mday); + + attributes->enableGps = true; + + return 0; +} + +int exynos_exif_attributes_create_params(struct exynos_camera *exynos_camera, + struct exynos_exif *exif) +{ + exif_attribute_t *attributes; + uint32_t av, tv, bv, sv, ev; + time_t time_data; + struct tm *time_info; + int rotation; + int shutter_speed; + int exposure_time; + int iso_speed; + int exposure; + int flash_results; + + int rc; + + if (exynos_camera == NULL || exif == NULL) + return -EINVAL; + + attributes = &exif->attributes; + + // Picture size + + attributes->width = exynos_camera->picture_width; + attributes->height = exynos_camera->picture_height; + + // Thumbnail + + attributes->widthThumb = exynos_camera->jpeg_thumbnail_width; + attributes->heightThumb = exynos_camera->jpeg_thumbnail_height; + attributes->enableThumb = true; + + // Orientation + + rotation = exynos_param_int_get(exynos_camera, "rotation"); + switch (rotation) { + case 90: + attributes->orientation = EXIF_ORIENTATION_90; + break; + case 180: + attributes->orientation = EXIF_ORIENTATION_180; + break; + case 270: + attributes->orientation = EXIF_ORIENTATION_270; + break; + case 0: + default: + attributes->orientation = EXIF_ORIENTATION_UP; + break; + } + + // Time + + time(&time_data); + time_info = localtime(&time_data); + strftime((char *) attributes->date_time, sizeof(attributes->date_time), + "%Y:%m:%d %H:%M:%S", time_info); + + attributes->focal_length.num = exynos_camera->camera_focal_length; + attributes->focal_length.den = EXIF_DEF_FOCAL_LEN_DEN; + + shutter_speed = 100; + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_TV, + &shutter_speed); + if (rc < 0) + ALOGE("%s: Unable to get shutter speed", __func__); + + attributes->shutter_speed.num = shutter_speed; + attributes->shutter_speed.den = 100; + + attributes->exposure_time.num = 1; + attributes->exposure_time.den = APEX_SHUTTER_TO_EXPOSURE(shutter_speed); + + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_ISO, + &iso_speed); + if (rc < 0) + ALOGE("%s: Unable to get iso", __func__); + + attributes->iso_speed_rating = iso_speed; + + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_FLASH, + &flash_results); + if (rc < 0) + ALOGE("%s: Unable to get flash", __func__); + + attributes->flash = flash_results; + + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_BV, + (int *) &bv); + if (rc < 0) { + ALOGE("%s: Unable to get bv", __func__); + goto bv_static; + } + + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_EBV, + (int *) &ev); + if (rc < 0) { + ALOGE("%s: Unable to get ebv", __func__); + goto bv_static; + } + + goto bv_ioctl; + +bv_static: + exposure = exynos_param_int_get(exynos_camera, "exposure-compensation"); + if (exposure < 0) + exposure = EV_DEFAULT; + + av = APEX_FNUM_TO_APERTURE((double) attributes->fnumber.num / + attributes->fnumber.den); + tv = APEX_EXPOSURE_TO_SHUTTER((double) attributes->exposure_time.num / + attributes->exposure_time.den); + sv = APEX_ISO_TO_FILMSENSITIVITY(iso_speed); + bv = av + tv - sv; + ev = exposure - EV_DEFAULT; + +bv_ioctl: + attributes->brightness.num = bv; + attributes->brightness.den = EXIF_DEF_APEX_DEN; + + if (exynos_camera->scene_mode == SCENE_MODE_BEACH_SNOW) { + attributes->exposure_bias.num = EXIF_DEF_APEX_DEN; + attributes->exposure_bias.den = EXIF_DEF_APEX_DEN; + } else { + attributes->exposure_bias.num = ev * EXIF_DEF_APEX_DEN; + attributes->exposure_bias.den = EXIF_DEF_APEX_DEN; + } + + switch (exynos_camera->camera_metering) { + case METERING_CENTER: + attributes->metering_mode = EXIF_METERING_CENTER; + break; + case METERING_MATRIX: + attributes->metering_mode = EXIF_METERING_AVERAGE; + break; + case METERING_SPOT: + attributes->metering_mode = EXIF_METERING_SPOT; + break; + default: + attributes->metering_mode = EXIF_METERING_AVERAGE; + break; + } + + if (exynos_camera->whitebalance == WHITE_BALANCE_AUTO || + exynos_camera->whitebalance == WHITE_BALANCE_BASE) + attributes->white_balance = EXIF_WB_AUTO; + else + attributes->white_balance = EXIF_WB_MANUAL; + + switch (exynos_camera->scene_mode) { + case SCENE_MODE_PORTRAIT: + attributes->scene_capture_type = EXIF_SCENE_PORTRAIT; + break; + case SCENE_MODE_LANDSCAPE: + attributes->scene_capture_type = EXIF_SCENE_LANDSCAPE; + break; + case SCENE_MODE_NIGHTSHOT: + attributes->scene_capture_type = EXIF_SCENE_NIGHT; + break; + default: + attributes->scene_capture_type = EXIF_SCENE_STANDARD; + break; + } + + rc = exynos_exif_attributes_create_gps(exynos_camera, exif); + if (rc < 0) { + ALOGE("%s: Unable to create GPS attributes", __func__); + return -1; + } + + return 0; +} + +int exynos_exif_write_data(void *exif_data, unsigned short tag, + unsigned short type, unsigned int count, unsigned int *offset, void *start, + void *data, int length) +{ + unsigned char *pointer; + int size; + + if (exif_data == NULL || data == NULL || length <= 0) + return -EINVAL; + + pointer = (unsigned char *) exif_data; + + memcpy(pointer, &tag, sizeof(tag)); + pointer += sizeof(tag); + + memcpy(pointer, &type, sizeof(type)); + pointer += sizeof(type); + + memcpy(pointer, &count, sizeof(count)); + pointer += sizeof(count); + + if (offset != NULL && start != NULL) { + memcpy(pointer, offset, sizeof(*offset)); + pointer += sizeof(*offset); + + memcpy((void *) ((int) start + *offset), data, count * length); + *offset += count * length; + } else { + memcpy(pointer, data, count * length); + pointer += 4; + } + + size = (int) pointer - (int) exif_data; + return size; +} + +int exynos_exif_start(struct exynos_camera *exynos_camera, struct exynos_exif *exif) +{ + int rc; + + if (exynos_camera == NULL || exif == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exif->enabled) { + ALOGE("Exif was already started"); + return -1; + } + + rc = exynos_exif_attributes_create_static(exynos_camera, exif); + if (rc < 0) { + ALOGE("%s: Unable to create exif attributes", __func__); + goto error; + } + + rc = exynos_exif_attributes_create_params(exynos_camera, exif); + if (rc < 0) { + ALOGE("%s: Unable to create exif parameters", __func__); + goto error; + } + + exif->enabled = 1; + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + return rc; +} + +void exynos_exif_stop(struct exynos_camera *exynos_camera, + struct exynos_exif *exif) +{ + if (exynos_camera == NULL || exif == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exif->enabled) { + ALOGE("Exif was already stopped"); + return; + } + + if (exif->memory != NULL && exif->memory->release != NULL) { + exif->memory->release(exif->memory); + exif->memory = NULL; + } + + exif->enabled = 0; +} + +int exynos_exif(struct exynos_camera *exynos_camera, struct exynos_exif *exif) +{ + // Markers + unsigned char exif_app1_marker[] = { 0xff, 0xe1 }; + unsigned char exif_app1_size[] = { 0x00, 0x00 }; + unsigned char exif_marker[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; + unsigned char tiff_marker[] = { 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 }; + + unsigned char user_comment_code[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; + unsigned char exif_ascii_prefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; + + void *jpeg_thumbnail_data; + int jpeg_thumbnail_size; + camera_memory_t *memory = NULL; + int memory_size; + exif_attribute_t *attributes; + void *exif_ifd_data_start = NULL; + void *exif_ifd_start = NULL; + void *exif_ifd_gps = NULL; + void *exif_ifd_thumb = NULL; + unsigned char *pointer; + unsigned int offset; + unsigned int value; + void *data; + int count; + int rc; + + if (exynos_camera == NULL || exif == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (!exif->enabled) { + ALOGE("Exif was not started"); + return -1; + } + + jpeg_thumbnail_data = exif->jpeg_thumbnail_data; + jpeg_thumbnail_size = exif->jpeg_thumbnail_size; + + if (jpeg_thumbnail_data == NULL || jpeg_thumbnail_size <= 0) { + ALOGE("%s: Invalid jpeg thumbnail", __func__); + goto error; + } + + attributes = &exif->attributes; + + memory_size = EXIF_FILE_SIZE + jpeg_thumbnail_size; + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(-1, memory_size, 1, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + memset(memory->data, 0, memory_size); + + pointer = (unsigned char *) memory->data; + exif_ifd_data_start = (void *) pointer; + + // Skip 4 bytes for APP1 marker + pointer += 4; + + // Copy EXIF marker + memcpy(pointer, exif_marker, sizeof(exif_marker)); + pointer += sizeof(exif_marker); + + // Copy TIFF marker + memcpy(pointer, tiff_marker, sizeof(tiff_marker)); + exif_ifd_start = (void *) pointer; + pointer += sizeof(tiff_marker); + + if (attributes->enableGps) + value = NUM_0TH_IFD_TIFF; + else + value = NUM_0TH_IFD_TIFF - 1; + + memcpy(pointer, &value, NUM_SIZE); + pointer += NUM_SIZE; + + offset = 8 + NUM_SIZE + value * IFD_SIZE + OFFSET_SIZE; + + // Write EXIF data + count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_WIDTH, + EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->width, sizeof(attributes->width)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_HEIGHT, + EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->height, sizeof(attributes->height)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_MAKE, + EXIF_TYPE_ASCII, strlen((char *) attributes->maker) + 1, &offset, exif_ifd_start, &attributes->maker, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_MODEL, + EXIF_TYPE_ASCII, strlen((char *) attributes->model) + 1, &offset, exif_ifd_start, &attributes->model, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_ORIENTATION, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->orientation, sizeof(attributes->orientation)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_SOFTWARE, + EXIF_TYPE_ASCII, strlen((char *) attributes->software) + 1, &offset, exif_ifd_start, &attributes->software, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_DATE_TIME, + EXIF_TYPE_ASCII, 20, &offset, exif_ifd_start, &attributes->date_time, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_YCBCR_POSITIONING, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->ycbcr_positioning, sizeof(attributes->ycbcr_positioning)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_EXIF_IFD_POINTER, + EXIF_TYPE_LONG, 1, NULL, NULL, &offset, sizeof(offset)); + pointer += count; + + if (attributes->enableGps) { + exif_ifd_gps = (void *) pointer; + pointer += IFD_SIZE; + } + + exif_ifd_thumb = (void *) pointer; + pointer += OFFSET_SIZE; + + pointer = (unsigned char *) exif_ifd_start; + pointer += offset; + + value = NUM_0TH_IFD_EXIF; + memcpy(pointer, &value, NUM_SIZE); + pointer += NUM_SIZE; + + offset += NUM_SIZE + NUM_0TH_IFD_EXIF * IFD_SIZE + OFFSET_SIZE; + + count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_TIME, + EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->exposure_time, sizeof(attributes->exposure_time)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_FNUMBER, + EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->fnumber, sizeof(attributes->fnumber)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_PROGRAM, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->exposure_program, sizeof(attributes->exposure_program)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_ISO_SPEED_RATING, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->iso_speed_rating, sizeof(attributes->iso_speed_rating)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_EXIF_VERSION, + EXIF_TYPE_UNDEFINED, 4, NULL, NULL, &attributes->exif_version, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_DATE_TIME_ORG, + EXIF_TYPE_ASCII, 20, &offset, exif_ifd_start, &attributes->date_time, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_DATE_TIME_DIGITIZE, + EXIF_TYPE_ASCII, 20, &offset, exif_ifd_start, &attributes->date_time, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_SHUTTER_SPEED, + EXIF_TYPE_SRATIONAL, 1, &offset, exif_ifd_start, &attributes->shutter_speed, sizeof(attributes->shutter_speed)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_APERTURE, + EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->aperture, sizeof(attributes->aperture)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_BRIGHTNESS, + EXIF_TYPE_SRATIONAL, 1, &offset, exif_ifd_start, &attributes->brightness, sizeof(attributes->brightness)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_BIAS, + EXIF_TYPE_SRATIONAL, 1, &offset, exif_ifd_start, &attributes->exposure_bias, sizeof(attributes->exposure_bias)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_MAX_APERTURE, + EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->max_aperture, sizeof(attributes->max_aperture)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_METERING_MODE, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->metering_mode, sizeof(attributes->metering_mode)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_FLASH, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->flash, sizeof(attributes->flash)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_FOCAL_LENGTH, + EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->focal_length, sizeof(attributes->focal_length)); + pointer += count; + + value = strlen((char *) attributes->user_comment) + 1; + memmove(attributes->user_comment + sizeof(user_comment_code), attributes->user_comment, value); + memcpy(attributes->user_comment, user_comment_code, sizeof(user_comment_code)); + + count = exynos_exif_write_data(pointer, EXIF_TAG_USER_COMMENT, + EXIF_TYPE_UNDEFINED, value + sizeof(user_comment_code), &offset, exif_ifd_start, &attributes->user_comment, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_COLOR_SPACE, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->color_space, sizeof(attributes->color_space)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_PIXEL_X_DIMENSION, + EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->width, sizeof(attributes->width)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_PIXEL_Y_DIMENSION, + EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->height, sizeof(attributes->height)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_MODE, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->exposure_mode, sizeof(attributes->exposure_mode)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_WHITE_BALANCE, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->white_balance, sizeof(attributes->white_balance)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_SCENCE_CAPTURE_TYPE, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->scene_capture_type, sizeof(attributes->scene_capture_type)); + pointer += count; + + value = 0; + memcpy(pointer, &value, OFFSET_SIZE); + pointer += OFFSET_SIZE; + + // GPS + if (attributes->enableGps) { + pointer = (unsigned char *) exif_ifd_gps; + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_IFD_POINTER, + EXIF_TYPE_LONG, 1, NULL, NULL, &offset, sizeof(offset)); + + pointer = (unsigned char *) exif_ifd_start + offset; + + if (attributes->gps_processing_method[0] == 0) + value = NUM_0TH_IFD_GPS - 1; + else + value = NUM_0TH_IFD_GPS; + + memcpy(pointer, &value, NUM_SIZE); + pointer += NUM_SIZE; + + offset += NUM_SIZE + value * IFD_SIZE + OFFSET_SIZE; + + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_VERSION_ID, + EXIF_TYPE_BYTE, 4, NULL, NULL, &attributes->gps_version_id, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LATITUDE_REF, + EXIF_TYPE_ASCII, 2, NULL, NULL, &attributes->gps_latitude_ref, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LATITUDE, + EXIF_TYPE_RATIONAL, 3, &offset, exif_ifd_start, &attributes->gps_latitude, sizeof(attributes->gps_latitude[0])); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LONGITUDE_REF, + EXIF_TYPE_ASCII, 2, NULL, NULL, &attributes->gps_longitude_ref, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LONGITUDE, + EXIF_TYPE_RATIONAL, 3, &offset, exif_ifd_start, &attributes->gps_longitude, sizeof(attributes->gps_longitude[0])); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_ALTITUDE_REF, + EXIF_TYPE_BYTE, 1, NULL, NULL, &attributes->gps_altitude_ref, sizeof(char)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_ALTITUDE, + EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->gps_altitude, sizeof(attributes->gps_altitude)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_TIMESTAMP, + EXIF_TYPE_RATIONAL, 3, &offset, exif_ifd_start, &attributes->gps_timestamp, sizeof(attributes->gps_timestamp[0])); + pointer += count; + + value = strlen((char *) attributes->gps_processing_method); + if (value > 0) { + value = value > 100 ? 100 : value; + + data = calloc(1, value + sizeof(exif_ascii_prefix)); + memcpy(data, &exif_ascii_prefix, sizeof(exif_ascii_prefix)); + memcpy((void *) ((int) data + (int) sizeof(exif_ascii_prefix)), attributes->gps_processing_method, value); + + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_PROCESSING_METHOD, + EXIF_TYPE_UNDEFINED, value + sizeof(exif_ascii_prefix), &offset, exif_ifd_start, data, sizeof(char)); + pointer += count; + + free(data); + } + + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_DATESTAMP, + EXIF_TYPE_ASCII, 11, &offset, exif_ifd_start, &attributes->gps_datestamp, 1); + pointer += count; + + value = 0; + memcpy(pointer, &value, OFFSET_SIZE); + pointer += OFFSET_SIZE; + } + + if (attributes->enableThumb) { + value = offset; + memcpy(exif_ifd_thumb, &value, OFFSET_SIZE); + + pointer = (unsigned char *) ((int) exif_ifd_start + (int) offset); + + value = NUM_1TH_IFD_TIFF; + memcpy(pointer, &value, NUM_SIZE); + pointer += NUM_SIZE; + + offset += NUM_SIZE + NUM_1TH_IFD_TIFF * IFD_SIZE + OFFSET_SIZE; + + count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_WIDTH, + EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->widthThumb, sizeof(attributes->widthThumb)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_HEIGHT, + EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->heightThumb, sizeof(attributes->heightThumb)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_COMPRESSION_SCHEME, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->compression_scheme, sizeof(attributes->compression_scheme)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_ORIENTATION, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->orientation, sizeof(attributes->orientation)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_X_RESOLUTION, + EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->x_resolution, sizeof(attributes->x_resolution)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_Y_RESOLUTION, + EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->y_resolution, sizeof(attributes->y_resolution)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_RESOLUTION_UNIT, + EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->resolution_unit, sizeof(attributes->resolution_unit)); + pointer += count; + + count = exynos_exif_write_data(pointer, EXIF_TAG_JPEG_INTERCHANGE_FORMAT, + EXIF_TYPE_LONG, 1, NULL, NULL, &offset, sizeof(offset)); + pointer += count; + + value = (unsigned int) jpeg_thumbnail_size; + + count = exynos_exif_write_data(pointer, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, + EXIF_TYPE_LONG, 1, NULL, NULL, &value, sizeof(value)); + pointer += count; + + value = 0; + memcpy(pointer, &value, OFFSET_SIZE); + + pointer = (unsigned char *) ((int) exif_ifd_start + (int) offset); + + memcpy(pointer, jpeg_thumbnail_data, jpeg_thumbnail_size); + offset += jpeg_thumbnail_size; + } else { + value = 0; + memcpy(exif_ifd_thumb, &value, OFFSET_SIZE); + + } + + pointer = (unsigned char *) exif_ifd_data_start; + + memcpy(pointer, exif_app1_marker, sizeof(exif_app1_marker)); + pointer += sizeof(exif_app1_marker); + + memory_size = offset + 10; + value = memory_size - 2; + exif_app1_size[0] = (value >> 8) & 0xff; + exif_app1_size[1] = value & 0xff; + + memcpy(pointer, exif_app1_size, sizeof(exif_app1_size)); + + exif->memory = memory; + exif->memory_size = memory_size; + + rc = 0; + goto complete; + +error: + if (memory != NULL && memory->release != NULL) { + memory->release(memory); + exif->memory = NULL; + } + + rc = -1; + +complete: + return rc; +} diff --git a/camera/exynos_ion.c b/camera/exynos_ion.c new file mode 100644 index 0000000..6adf7cc --- /dev/null +++ b/camera/exynos_ion.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define LOG_TAG "exynos_ion" +#include + +#include "exynos_camera.h" + +int exynos_ion_init(struct exynos_camera *exynos_camera) +{ + exynos_camera->ion_fd = -1; + + return 0; +} + +int exynos_ion_open(struct exynos_camera *exynos_camera) +{ + int fd; + + fd = open("/dev/ion", O_RDWR); + if (fd < 0) { + ALOGE("%s: Unable to open ion device", __func__); + return -1; + } + + exynos_camera->ion_fd = fd; + + return 0; +} + +void exynos_ion_close(struct exynos_camera *exynos_camera) +{ + if (exynos_camera->ion_fd >= 0) + close(exynos_camera->ion_fd); + + exynos_camera->ion_fd = -1; +} + +int exynos_ion_alloc(struct exynos_camera *exynos_camera, int size) +{ + struct ion_allocation_data alloc_data; + struct ion_fd_data share_data; + struct ion_handle_data free_data; + int page_size; + int fd; + int rc; + + page_size = getpagesize(); + + fd = exynos_camera->ion_fd; + if (fd < 0) + return -1; + + memset(&alloc_data, 0, sizeof(alloc_data)); + alloc_data.len = size; + alloc_data.align = page_size; + alloc_data.flags = ION_HEAP_EXYNOS_CONTIG_MASK; + + rc = ioctl(fd, ION_IOC_ALLOC, &alloc_data); + if (rc < 0) + return -1; + + memset(&share_data, 0, sizeof(share_data)); + share_data.handle = alloc_data.handle; + + rc = ioctl(fd, ION_IOC_SHARE, &share_data); + if (rc < 0) + return -1; + + memset(&free_data, 0, sizeof(free_data)); + free_data.handle = alloc_data.handle; + + rc = ioctl(fd, ION_IOC_FREE, &free_data); + if (rc < 0) + return -1; + + return share_data.fd; +} + +int exynos_ion_free(struct exynos_camera *exynos_camera, int fd) +{ + close(fd); + return 0; +} + +int exynos_ion_phys(struct exynos_camera *exynos_camera, int fd) +{ + struct ion_custom_data custom_data; + struct ion_phys_data phys_data; + int rc; + + memset(&phys_data, 0, sizeof(phys_data)); + phys_data.fd_buffer = fd; + + memset(&custom_data, 0, sizeof(custom_data)); + custom_data.cmd = ION_EXYNOS_CUSTOM_PHYS; + custom_data.arg = (unsigned long) &phys_data; + + fd = exynos_camera->ion_fd; + if (fd < 0) + return -1; + + rc = ioctl(fd, ION_IOC_CUSTOM, &custom_data); + if (rc < 0) + return -1; + + return (int) phys_data.phys; +} + +int exynos_ion_msync(struct exynos_camera *exynos_camera, int fd, + int offset, int size) +{ + struct ion_custom_data custom_data; + struct ion_msync_data msync_data; + int rc; + + memset(&msync_data, 0, sizeof(msync_data)); + msync_data.dir = IMSYNC_SYNC_FOR_DEV | IMSYNC_DEV_TO_RW; + msync_data.fd_buffer = fd; + msync_data.offset = offset; + msync_data.size = size; + + memset(&custom_data, 0, sizeof(custom_data)); + custom_data.cmd = ION_EXYNOS_CUSTOM_MSYNC; + custom_data.arg = (unsigned long) &msync_data; + + fd = exynos_camera->ion_fd; + if (fd < 0) + return -1; + + rc = ioctl(fd, ION_IOC_CUSTOM, &custom_data); + if (rc < 0) + return -1; + + return 0; +} diff --git a/camera/exynos_jpeg.c b/camera/exynos_jpeg.c new file mode 100644 index 0000000..24e74fc --- /dev/null +++ b/camera/exynos_jpeg.c @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define LOG_TAG "exynos_jpeg" +#include + +#include "exynos_camera.h" + +#ifdef EXYNOS_JPEG_HW +int exynos_jpeg_start(struct exynos_camera *exynos_camera, + struct exynos_jpeg *jpeg) +{ + struct jpeg_config config; + struct jpeg_buf *buffer_in; + struct jpeg_buf *buffer_out; + camera_memory_t *memory = NULL; +#ifdef EXYNOS_ION + int memory_ion_fd = -1; +#endif + int address; + int fd = -1; + int rc; + + if (exynos_camera == NULL || jpeg == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (jpeg->enabled) { + ALOGE("Jpeg was already started"); + return -1; + } + + buffer_in = &jpeg->buffer_in; + buffer_out = &jpeg->buffer_out; + +#ifdef EXYNOS_ION + jpeg->memory_in_ion_fd = -1; + jpeg->memory_out_ion_fd = -1; +#endif + + fd = jpeghal_enc_init(); + if (fd < 0) { + ALOGE("%s: Unable to init jpeg encoder", __func__); + goto error; + } + + jpeg->fd = fd; + + memset(&config, 0, sizeof(config)); + config.mode = JPEG_ENCODE; + config.width = jpeg->width; + config.height = jpeg->height; + config.num_planes = 1; + config.pix.enc_fmt.in_fmt = jpeg->format; + config.pix.enc_fmt.out_fmt = V4L2_PIX_FMT_JPEG_420; + + if (jpeg->quality >= 90) + config.enc_qual = QUALITY_LEVEL_1; + else if (jpeg->quality >= 80) + config.enc_qual = QUALITY_LEVEL_2; + else if (jpeg->quality >= 70) + config.enc_qual = QUALITY_LEVEL_3; + else + config.enc_qual = QUALITY_LEVEL_4; + + rc = jpeghal_enc_setconfig(fd, &config); + if (rc < 0) { + ALOGE("%s: Unable to set jpeg config", __func__); + goto error; + } + + rc = jpeghal_s_ctrl(fd, V4L2_CID_CACHEABLE, 1); + if (rc < 0) { + ALOGE("%s: Unable to set cacheable control", __func__); + goto error; + } + + memset(buffer_in, 0, sizeof(struct jpeg_buf)); + buffer_in->memory = V4L2_MEMORY_MMAP; + buffer_in->num_planes = 1; + + memset(buffer_out, 0, sizeof(struct jpeg_buf)); + buffer_out->memory = V4L2_MEMORY_MMAP; + buffer_out->num_planes = 1; + + rc = jpeghal_set_inbuf(fd, buffer_in); + if (rc < 0) { +#ifdef EXYNOS_ION + // Input + + buffer_in->memory = V4L2_MEMORY_USERPTR; + buffer_in->length[0] = exynos_camera_buffer_length(jpeg->width, jpeg->height, jpeg->format); + + memory_ion_fd = exynos_ion_alloc(exynos_camera, buffer_in->length[0]); + if (memory_ion_fd < 0) { + ALOGE("%s: Unable to alloc input ION memory", __func__); + goto error; + } + + address = exynos_ion_phys(exynos_camera, memory_ion_fd); + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(memory_ion_fd, buffer_in->length[0], 1, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + jpeg->memory_in = memory; + jpeg->memory_in_pointer = memory->data; + jpeg->memory_in_ion_fd = memory_ion_fd; + buffer_in->start[0] = (void *) address; + + rc = jpeghal_set_inbuf(fd, buffer_in); + if (rc < 0) { + ALOGE("%s: Unable to set input buffer", __func__); + goto error; + } + + // Output + + buffer_out->memory = V4L2_MEMORY_USERPTR; + buffer_out->length[0] = jpeg->width * jpeg->height * 4; + + memory_ion_fd = exynos_ion_alloc(exynos_camera, buffer_out->length[0]); + if (memory_ion_fd < 0) { + ALOGE("%s: Unable to alloc output ION memory", __func__); + goto error; + } + + address = exynos_ion_phys(exynos_camera, memory_ion_fd); + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(memory_ion_fd, buffer_out->length[0], 1, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + jpeg->memory_out = memory; + jpeg->memory_out_pointer = memory->data; + jpeg->memory_out_ion_fd = memory_ion_fd; + buffer_out->start[0] = (void *) address; +#else + ALOGE("%s: Unable to set input buffer", __func__); + goto error; +#endif + } else { + jpeg->memory_in_pointer = buffer_in->start[0]; + jpeg->memory_out_pointer = buffer_out->start[0]; + } + + rc = jpeghal_set_outbuf(fd, buffer_out); + if (rc < 0) { + ALOGE("%s: Unable to set output buffer", __func__); + goto error; + } + + jpeg->enabled = 1; + + rc = 0; + goto complete; + +error: + if (fd >= 0) { + // Avoid releasing unrequested mmap buffers + + if (buffer_in->memory == 0) + buffer_in->memory = V4L2_MEMORY_USERPTR; + + if (buffer_out->memory == 0) + buffer_out->memory = V4L2_MEMORY_USERPTR; + + jpeghal_deinit(fd, buffer_in, buffer_out); + jpeg->fd = -1; + } + + if (jpeg->memory_in != NULL && jpeg->memory_in->release != NULL) { + jpeg->memory_in->release(jpeg->memory_in); + jpeg->memory_in = NULL; +#ifdef EXYNOS_ION + if (jpeg->memory_in_ion_fd >= 0) { + exynos_ion_free(exynos_camera, jpeg->memory_in_ion_fd); + jpeg->memory_in_ion_fd = -1; + } +#endif + } + + if (jpeg->memory_out != NULL && jpeg->memory_out->release != NULL) { + jpeg->memory_out->release(jpeg->memory_out); + jpeg->memory_out = NULL; + +#ifdef EXYNOS_ION + if (jpeg->memory_out_ion_fd >= 0) { + exynos_ion_free(exynos_camera, jpeg->memory_out_ion_fd); + jpeg->memory_out_ion_fd = -1; + } +#endif + } + + rc = -1; + +complete: + return rc; +} + +void exynos_jpeg_stop(struct exynos_camera *exynos_camera, + struct exynos_jpeg *jpeg) +{ + struct jpeg_buf *buffer_in; + struct jpeg_buf *buffer_out; + int fd = -1; + int rc; + + if (exynos_camera == NULL || jpeg == NULL) + return; + + ALOGD("%s()", __func__); + + if (!jpeg->enabled) { + ALOGE("Jpeg was already stopped"); + return; + } + + buffer_in = &jpeg->buffer_in; + buffer_out = &jpeg->buffer_out; + + fd = jpeg->fd; + + if (fd >= 0) { + jpeghal_deinit(fd, buffer_in, buffer_out); + jpeg->fd = -1; + } + + if (jpeg->memory_in != NULL && jpeg->memory_in->release != NULL) { + jpeg->memory_in->release(jpeg->memory_in); + jpeg->memory_in = NULL; +#ifdef EXYNOS_ION + if (jpeg->memory_in_ion_fd >= 0) { + exynos_ion_free(exynos_camera, jpeg->memory_in_ion_fd); + jpeg->memory_in_ion_fd = -1; + } +#endif + } + + if (jpeg->memory_out != NULL && jpeg->memory_out->release != NULL) { + jpeg->memory_out->release(jpeg->memory_out); + jpeg->memory_out = NULL; + +#ifdef EXYNOS_ION + if (jpeg->memory_out_ion_fd >= 0) { + exynos_ion_free(exynos_camera, jpeg->memory_out_ion_fd); + jpeg->memory_out_ion_fd = -1; + } +#endif + } + + jpeg->enabled = 0; +} + +int exynos_jpeg(struct exynos_camera *exynos_camera, struct exynos_jpeg *jpeg) +{ + struct jpeg_buf *buffer_in; + struct jpeg_buf *buffer_out; + int memory_size; + int fd = -1; + int rc; + + if (exynos_camera == NULL || jpeg == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (!jpeg->enabled) { + ALOGE("Jpeg was not started"); + return -1; + } + + buffer_in = &jpeg->buffer_in; + buffer_out = &jpeg->buffer_out; + + fd = jpeg->fd; + if (fd < 0) { + ALOGE("%s: Invalid jpeg fd", __func__); + goto error; + } + +#ifdef EXYNOS_ION + if (jpeg->memory_in != NULL && jpeg->memory_in_ion_fd >= 0) { + rc = exynos_ion_msync(exynos_camera, jpeg->memory_in_ion_fd, 0, buffer_in->length[0]); + if (rc < 0) { + ALOGE("%s: Unable to sync ION memory", __func__); + goto error; + } + } +#endif + + rc = jpeghal_enc_exe(fd, buffer_in, buffer_out); + if (rc < 0) { + ALOGE("%s: Unable to encode jpeg", __func__); + goto error; + } + + memory_size = jpeghal_g_ctrl(fd, V4L2_CID_CAM_JPEG_ENCODEDSIZE); + if (memory_size <= 0) { + ALOGE("%s: Unable to get jpeg size", __func__); + goto error; + } + + jpeg->memory_out_size = memory_size; + +#ifdef EXYNOS_ION + if (jpeg->memory_out != NULL && jpeg->memory_out_ion_fd >= 0) { + rc = exynos_ion_msync(exynos_camera, jpeg->memory_out_ion_fd, 0, memory_size); + if (rc < 0) { + ALOGE("%s: Unable to sync ION memory", __func__); + goto error; + } + } +#endif + + rc = 0; + goto complete; + +error: + if (fd >= 0) { + // Avoid releasing unrequested mmap buffers + + if (buffer_in->memory == 0) + buffer_in->memory = V4L2_MEMORY_USERPTR; + + if (buffer_out->memory == 0) + buffer_out->memory = V4L2_MEMORY_USERPTR; + + jpeghal_deinit(fd, buffer_in, buffer_out); + jpeg->fd = -1; + } + + if (jpeg->memory_in != NULL && jpeg->memory_in->release != NULL) { + jpeg->memory_in->release(jpeg->memory_in); + jpeg->memory_in = NULL; + +#ifdef EXYNOS_ION + if (jpeg->memory_in_ion_fd >= 0) { + exynos_ion_free(exynos_camera, jpeg->memory_in_ion_fd); + jpeg->memory_in_ion_fd = -1; + } +#endif + } + + if (jpeg->memory_out != NULL && jpeg->memory_out->release != NULL) { + jpeg->memory_out->release(jpeg->memory_out); + jpeg->memory_out = NULL; + +#ifdef EXYNOS_ION + if (jpeg->memory_out_ion_fd >= 0) { + exynos_ion_free(exynos_camera, jpeg->memory_out_ion_fd); + jpeg->memory_out_ion_fd = -1; + } +#endif + } + + rc = -1; + +complete: + return rc; +} +#endif diff --git a/camera/exynos_param.c b/camera/exynos_param.c new file mode 100644 index 0000000..f41f4f6 --- /dev/null +++ b/camera/exynos_param.c @@ -0,0 +1,492 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define LOG_TAG "exynos_param" +#include + +#include "exynos_camera.h" + +int exynos_param_register(struct exynos_camera *exynos_camera, char *key, + union exynos_param_data data, enum exynos_param_type type) +{ + struct list_head *list_end; + struct list_head *list; + struct exynos_param *param; + + if (exynos_camera == NULL || key == NULL) + return -EINVAL; + + param = (struct exynos_param *) calloc(1, sizeof(struct exynos_param)); + if (param == NULL) + return -ENOMEM; + + param->key = strdup(key); + switch (type) { + case EXYNOS_PARAM_INT: + param->data.integer = data.integer; + break; + case EXYNOS_PARAM_FLOAT: + param->data.floating = data.floating; + break; + case EXYNOS_PARAM_STRING: + param->data.string = strdup(data.string); + break; + default: + ALOGE("%s: Invalid type", __func__); + goto error; + } + param->type = type; + + list_end = (struct list_head *) exynos_camera->params; + while (list_end != NULL && list_end->next != NULL) + list_end = list_end->next; + + list = (struct list_head *) param; + list_head_insert(list, list_end, NULL); + + if (exynos_camera->params == NULL) + exynos_camera->params = param; + + return 0; + +error: + if (param != NULL) { + if (param->key != NULL) + free(param->key); + + free(param); + } + + return -1; +} + +void exynos_param_unregister(struct exynos_camera *exynos_camera, + struct exynos_param *param) +{ + struct list_head *list; + + if (exynos_camera == NULL || param == NULL) + return; + + list = (struct list_head *) exynos_camera->params; + while (list != NULL) { + if ((void *) list == (void *) param) { + list_head_remove(list); + + if ((void *) list == (void *) exynos_camera->params) + exynos_camera->params = (struct exynos_param *) list->next; + + if (param->type == EXYNOS_PARAM_STRING && param->data.string != NULL) + free(param->data.string); + + memset(param, 0, sizeof(struct exynos_param)); + free(param); + + break; + } + +list_continue: + list = list->next; + } +} + +struct exynos_param *exynos_param_find_key(struct exynos_camera *exynos_camera, + char *key) +{ + struct exynos_param *param; + struct list_head *list; + + if (exynos_camera == NULL || key == NULL) + return NULL; + + list = (struct list_head *) exynos_camera->params; + while (list != NULL) { + param = (struct exynos_param *) list; + if (param->key == NULL) + goto list_continue; + + if (strcmp(param->key, key) == 0) + return param; + +list_continue: + list = list->next; + } + + return NULL; +} + +int exynos_param_data_set(struct exynos_camera *exynos_camera, char *key, + union exynos_param_data data, enum exynos_param_type type) +{ + struct exynos_param *param; + + if (exynos_camera == NULL || key == NULL) + return -EINVAL; + + if (strchr(key, '=') || strchr(key, ';')) + return -EINVAL; + + if (type == EXYNOS_PARAM_STRING && data.string != NULL && + (strchr(data.string, '=') || strchr(data.string, ';'))) + return -EINVAL; + + param = exynos_param_find_key(exynos_camera, key); + if (param == NULL) { + // The key isn't in the list yet + exynos_param_register(exynos_camera, key, data, type); + return 0; + } + + if (param->type != type) + ALOGE("%s: Mismatching types for key %s", __func__, key); + + if (param->type == EXYNOS_PARAM_STRING && param->data.string != NULL) + free(param->data.string); + + switch (type) { + case EXYNOS_PARAM_INT: + param->data.integer = data.integer; + break; + case EXYNOS_PARAM_FLOAT: + param->data.floating = data.floating; + break; + case EXYNOS_PARAM_STRING: + param->data.string = strdup(data.string); + break; + default: + ALOGE("%s: Invalid type", __func__); + return -1; + } + param->type = type; + + return 0; +} + +int exynos_param_data_get(struct exynos_camera *exynos_camera, char *key, + union exynos_param_data *data, enum exynos_param_type type) +{ + struct exynos_param *param; + + if (exynos_camera == NULL || key == NULL || data == NULL) + return -EINVAL; + + param = exynos_param_find_key(exynos_camera, key); + if (param == NULL || param->type != type) + return -1; + + memcpy(data, ¶m->data, sizeof(param->data)); + + return 0; +} + +int exynos_param_int_get(struct exynos_camera *exynos_camera, + char *key) +{ + union exynos_param_data data; + int rc; + + if (exynos_camera == NULL || key == NULL) + return -EINVAL; + + rc = exynos_param_data_get(exynos_camera, key, &data, EXYNOS_PARAM_INT); + if (rc < 0) { + ALOGE("%s: Unable to get data for key %s", __func__, key); + return -1; + } + + return data.integer; +} + +float exynos_param_float_get(struct exynos_camera *exynos_camera, + char *key) +{ + union exynos_param_data data; + int rc; + + if (exynos_camera == NULL || key == NULL) + return -EINVAL; + + rc = exynos_param_data_get(exynos_camera, key, &data, EXYNOS_PARAM_FLOAT); + if (rc < 0) { + ALOGE("%s: Unable to get data for key %s", __func__, key); + return -1; + } + + return data.floating; +} + +char *exynos_param_string_get(struct exynos_camera *exynos_camera, + char *key) +{ + union exynos_param_data data; + int rc; + + if (exynos_camera == NULL || key == NULL) + return NULL; + + rc = exynos_param_data_get(exynos_camera, key, &data, EXYNOS_PARAM_STRING); + if (rc < 0) { + ALOGE("%s: Unable to get data for key %s", __func__, key); + return NULL; + } + + return data.string; +} + +int exynos_param_int_set(struct exynos_camera *exynos_camera, + char *key, int integer) +{ + union exynos_param_data data; + int rc; + + if (exynos_camera == NULL || key == NULL) + return -EINVAL; + + data.integer = integer; + + rc = exynos_param_data_set(exynos_camera, key, data, EXYNOS_PARAM_INT); + if (rc < 0) { + ALOGE("%s: Unable to set data for key %s", __func__, key); + return -1; + } + + return 0; +} + +int exynos_param_float_set(struct exynos_camera *exynos_camera, + char *key, float floating) +{ + union exynos_param_data data; + int rc; + + if (exynos_camera == NULL || key == NULL) + return -EINVAL; + + data.floating = floating; + + rc = exynos_param_data_set(exynos_camera, key, data, EXYNOS_PARAM_FLOAT); + if (rc < 0) { + ALOGE("%s: Unable to set data for key %s", __func__, key); + return -1; + } + + return 0; +} + +int exynos_param_string_set(struct exynos_camera *exynos_camera, + char *key, char *string) +{ + union exynos_param_data data; + int rc; + + if (exynos_camera == NULL || key == NULL || string == NULL) + return -EINVAL; + + data.string = string; + + rc = exynos_param_data_set(exynos_camera, key, data, EXYNOS_PARAM_STRING); + if (rc < 0) { + ALOGE("%s: Unable to set data for key %s", __func__, key); + return -1; + } + + return 0; +} + +char *exynos_params_string_get(struct exynos_camera *exynos_camera) +{ + struct exynos_param *param; + struct list_head *list; + char *string = NULL; + char *s = NULL; + int length = 0; + int l = 0; + + if (exynos_camera == NULL) + return NULL; + + list = (struct list_head *) exynos_camera->params; + while (list != NULL) { + param = (struct exynos_param *) list; + if (param->key == NULL) + goto list_continue_length; + + length += strlen(param->key); + length++; + + switch (param->type) { + case EXYNOS_PARAM_INT: + case EXYNOS_PARAM_FLOAT: + length += 16; + break; + case EXYNOS_PARAM_STRING: + length += strlen(param->data.string); + break; + default: + ALOGE("%s: Invalid type", __func__); + return NULL; + } + + length++; + +list_continue_length: + list = list->next; + } + + if (length == 0) + return NULL; + + string = calloc(1, length); + s = string; + + list = (struct list_head *) exynos_camera->params; + while (list != NULL) { + param = (struct exynos_param *) list; + if (param->key == NULL) + goto list_continue; + + l = sprintf(s, "%s=", param->key); + s += l; + + switch (param->type) { + case EXYNOS_PARAM_INT: + l = snprintf(s, 16, "%d", param->data.integer); + s += l; + break; + case EXYNOS_PARAM_FLOAT: + l = snprintf(s, 16, "%g", param->data.floating); + s += l; + break; + case EXYNOS_PARAM_STRING: + l = sprintf(s, "%s", param->data.string); + s += l; + break; + default: + ALOGE("%s: Invalid type", __func__); + return NULL; + } + + if (list->next != NULL) { + *s = ';'; + s++; + } else { + *s = '\0'; + break; + } + +list_continue: + list = list->next; + } + + return string; +} + +int exynos_params_string_set(struct exynos_camera *exynos_camera, char *string) +{ + union exynos_param_data data; + enum exynos_param_type type; + + char *d = NULL; + char *s = NULL; + char *k = NULL; + char *v = NULL; + + char *key; + char *value; + + int rc; + int i; + + if (exynos_camera == NULL || string == NULL) + return -1; + + d = strdup(string); + s = d; + + while (1) { + k = strchr(s, '='); + if (k == NULL) + break; + *k = '\0'; + key = s; + + v = strchr(k+1, ';'); + if (v != NULL) + *v = '\0'; + value = k+1; + + k = value; + if (isdigit(k[0]) || k[0] == '-') { + type = EXYNOS_PARAM_INT; + + for (i=1 ; k[i] != '\0' ; i++) { + if (k[i] == '.') { + type = EXYNOS_PARAM_FLOAT; + } else if (!isdigit(k[i])) { + type = EXYNOS_PARAM_STRING; + break; + } + } + } else { + type = EXYNOS_PARAM_STRING; + } + + switch (type) { + case EXYNOS_PARAM_INT: + data.integer = atoi(value); + break; + case EXYNOS_PARAM_FLOAT: + data.floating = atof(value); + break; + case EXYNOS_PARAM_STRING: + data.string = value; + break; + default: + ALOGE("%s: Invalid type", __func__); + goto error; + } + + rc = exynos_param_data_set(exynos_camera, key, data, type); + if (rc < 0) { + ALOGE("%s: Unable to set data for key %s", __func__, key); + goto error; + } + + if (v == NULL) + break; + + s = v+1; + } + + if (d != NULL) + free(d); + + return 0; + +error: + if (d != NULL) + free(d); + + return -1; +} diff --git a/camera/exynos_utils.c b/camera/exynos_utils.c new file mode 100644 index 0000000..c969656 --- /dev/null +++ b/camera/exynos_utils.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define LOG_TAG "exynos_utils" +#include + +#include "exynos_camera.h" + +int list_head_insert(struct list_head *list, struct list_head *prev, + struct list_head *next) +{ + if (list == NULL) + return -EINVAL; + + list->prev = prev; + list->next = next; + + if(prev != NULL) + prev->next = list; + if(next != NULL) + next->prev = list; + + return 0; +} + +void list_head_remove(struct list_head *list) +{ + if(list == NULL) + return; + + if(list->next != NULL) + list->next->prev = list->prev; + if(list->prev != NULL) + list->prev->next = list->next; +} + + +int exynos_camera_buffer_length(int width, int height, int format) +{ + float bpp; + int buffer_length; + + switch (format) { + case V4L2_PIX_FMT_RGB32: + bpp = 4.0f; + buffer_length = (int) ((float) width * (float) height * bpp); + break; + case V4L2_PIX_FMT_RGB565: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_YUV422P: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + bpp = 2.0f; + buffer_length = (int) ((float) width * (float) height * bpp); + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + bpp = 1.5f; + buffer_length = EXYNOS_CAMERA_ALIGN(width * height); + buffer_length += EXYNOS_CAMERA_ALIGN(width * height / 2); + break; + case V4L2_PIX_FMT_NV21: + bpp = 1.5f; + buffer_length = (int) ((float) width * (float) height * bpp); + break; + case V4L2_PIX_FMT_JPEG: + case V4L2_PIX_FMT_INTERLEAVED: + default: + buffer_length = -1; + bpp = 0; + break; + } + + return buffer_length; +} + +void exynos_camera_yuv_planes(int width, int height, int format, int address, int *address_y, int *address_cb, int *address_cr) +{ + switch (format) { + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_RGB565: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_YVYU: + if (address_y != NULL) + *address_y = address; + break; + case V4L2_PIX_FMT_YUV420: + if (address_y != NULL) + *address_y = address; + + address += EXYNOS_CAMERA_ALIGN(width * height); + + if (address_cb != NULL) + *address_cb = address; + + address += EXYNOS_CAMERA_ALIGN(width * height / 4); + + if (address_cr != NULL) + *address_cr = address; + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + if (address_y != NULL) + *address_y = address; + + address += EXYNOS_CAMERA_ALIGN(width * height); + + if (address_cb != NULL) + *address_cb = address; + + if (address_cr != NULL) + *address_cr = address; + break; + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + default: + if (address_y != NULL) + *address_y = address; + + address += width * height; + + if (address_cb != NULL) + *address_cb = address; + + if (address_cr != NULL) + *address_cr = address; + break; + } +} diff --git a/camera/exynos_v4l2.c b/camera/exynos_v4l2.c new file mode 100644 index 0000000..2e7fdaf --- /dev/null +++ b/camera/exynos_v4l2.c @@ -0,0 +1,739 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * Based on crespo libcamera and exynos4 hal libcamera: + * Copyright 2008, The Android Open Source Project + * Copyright 2010, Samsung Electronics Co. LTD + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define LOG_TAG "exynos_v4l2" +#include + +#include "exynos_camera.h" + +int exynos_v4l2_init(struct exynos_camera *exynos_camera) +{ + int i; + + for (i = 0; i < EXYNOS_CAMERA_MAX_V4L2_NODES_COUNT; i++) + exynos_camera->v4l2_fds[i] = -1; + + return 0; +} + +int exynos_v4l2_index(struct exynos_camera *exynos_camera, int exynos_v4l2_id) +{ + int index; + int i; + + if (exynos_camera == NULL || exynos_camera->config == NULL || + exynos_camera->config->v4l2_nodes == NULL) + return -EINVAL; + + if (exynos_v4l2_id > exynos_camera->config->v4l2_nodes_count) + return -1; + + index = -1; + for (i = 0; i < exynos_camera->config->v4l2_nodes_count; i++) { + if (exynos_camera->config->v4l2_nodes[i].id == exynos_v4l2_id && + exynos_camera->config->v4l2_nodes[i].node != NULL) { + index = i; + } + } + + return index; +} + +int exynos_v4l2_fd(struct exynos_camera *exynos_camera, int exynos_v4l2_id) +{ + int index; + + if (exynos_camera == NULL) + return -EINVAL; + + index = exynos_v4l2_index(exynos_camera, exynos_v4l2_id); + if (index < 0) { + ALOGE("%s: Unable to get v4l2 index for id %d", __func__, exynos_v4l2_id); + return -1; + } + + return exynos_camera->v4l2_fds[index]; +} + +int exynos_v4l2_open(struct exynos_camera *exynos_camera, int exynos_v4l2_id) +{ + char *node; + int index; + int fd; + + if (exynos_camera == NULL || exynos_camera->config == NULL || + exynos_camera->config->v4l2_nodes == NULL) + return -EINVAL; + + index = exynos_v4l2_index(exynos_camera, exynos_v4l2_id); + if (index < 0) { + ALOGE("%s: Unable to get v4l2 node for id %d", __func__, exynos_v4l2_id); + return -1; + } + + node = exynos_camera->config->v4l2_nodes[index].node; + fd = open(node, O_RDWR); + if (fd < 0) { + ALOGE("%s: Unable to open v4l2 node for id %d", __func__, exynos_v4l2_id); + return -1; + } + + exynos_camera->v4l2_fds[index] = fd; + + return 0; +} + +void exynos_v4l2_close(struct exynos_camera *exynos_camera, int exynos_v4l2_id) +{ + int index; + + if (exynos_camera == NULL || exynos_camera->config == NULL || + exynos_camera->config->v4l2_nodes == NULL) + return; + + index = exynos_v4l2_index(exynos_camera, exynos_v4l2_id); + if (index < 0) { + ALOGE("%s: Unable to get v4l2 node for id %d", __func__, exynos_v4l2_id); + return; + } + + if (exynos_camera->v4l2_fds[index] >= 0) + close(exynos_camera->v4l2_fds[index]); + + exynos_camera->v4l2_fds[index] = -1; +} + +int exynos_v4l2_ioctl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int request, void *data) +{ + int fd; + + if (exynos_camera == NULL) + return -EINVAL; + + fd = exynos_v4l2_fd(exynos_camera, exynos_v4l2_id); + if (fd < 0) { + ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, exynos_v4l2_id); + return -1; + } + + return ioctl(fd, request, data); +} + +int exynos_v4l2_poll(struct exynos_camera *exynos_camera, int exynos_v4l2_id) +{ + struct pollfd events; + int fd; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + fd = exynos_v4l2_fd(exynos_camera, exynos_v4l2_id); + if (fd < 0) { + ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, exynos_v4l2_id); + return -1; + } + + memset(&events, 0, sizeof(events)); + events.fd = fd; + events.events = POLLIN | POLLERR; + + rc = poll(&events, 1, 1000); + if (rc < 0 || events.revents & POLLERR) + return -1; + + return rc; +} + +int exynos_v4l2_qbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int memory, int index, unsigned long userptr) +{ + struct v4l2_buffer buffer; + int rc; + + if (exynos_camera == NULL || index < 0) + return -EINVAL; + + memset(&buffer, 0, sizeof(buffer)); + buffer.type = type; + buffer.memory = memory; + buffer.index = index; + + if (userptr) + buffer.m.userptr = userptr; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QBUF, &buffer); + return rc; +} + +int exynos_v4l2_qbuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int index) +{ + return exynos_v4l2_qbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP, index, 0); +} + +int exynos_v4l2_qbuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int index, unsigned long userptr) +{ + return exynos_v4l2_qbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR, index, userptr); +} + +int exynos_v4l2_dqbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int memory) +{ + struct v4l2_buffer buffer; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + memset(&buffer, 0, sizeof(buffer)); + buffer.type = type; + buffer.memory = memory; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_DQBUF, &buffer); + if (rc < 0) + return rc; + + return buffer.index; +} + +int exynos_v4l2_dqbuf_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_dqbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP); +} + +int exynos_v4l2_dqbuf_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_dqbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR); +} + +int exynos_v4l2_reqbufs(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int memory, int count) +{ + struct v4l2_requestbuffers requestbuffers; + int rc; + + if (exynos_camera == NULL || count < 0) + return -EINVAL; + + requestbuffers.type = type; + requestbuffers.count = count; + requestbuffers.memory = memory; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_REQBUFS, &requestbuffers); + if (rc < 0) + return rc; + + return requestbuffers.count; +} + +int exynos_v4l2_reqbufs_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int count) +{ + return exynos_v4l2_reqbufs(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP, count); +} + +int exynos_v4l2_reqbufs_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int count) +{ + return exynos_v4l2_reqbufs(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR, count); +} + +int exynos_v4l2_querybuf(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int memory, int index) +{ + struct v4l2_buffer buffer; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + memset(&buffer, 0, sizeof(buffer)); + buffer.type = type; + buffer.memory = memory; + buffer.index = index; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QUERYBUF, &buffer); + if (rc < 0) + return rc; + + return buffer.length; +} + +int exynos_v4l2_querybuf_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int index) +{ + return exynos_v4l2_querybuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP, index); +} + +int exynos_v4l2_querybuf_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int index) +{ + return exynos_v4l2_querybuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR, index); +} + +int exynos_v4l2_querycap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int flags) +{ + struct v4l2_capability cap; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QUERYCAP, &cap); + if (rc < 0) + return rc; + + if (!(cap.capabilities & flags)) + return -1; + + return 0; +} + +int exynos_v4l2_querycap_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_querycap(exynos_camera, exynos_v4l2_id, V4L2_CAP_VIDEO_CAPTURE); +} + +int exynos_v4l2_querycap_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_querycap(exynos_camera, exynos_v4l2_id, V4L2_CAP_VIDEO_OUTPUT); +} + +int exynos_v4l2_streamon(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type) +{ + enum v4l2_buf_type buf_type; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + buf_type = type; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_STREAMON, &buf_type); + return rc; +} + +int exynos_v4l2_streamon_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_streamon(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE); +} + +int exynos_v4l2_streamon_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_streamon(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT); +} + +int exynos_v4l2_streamoff(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type) +{ + enum v4l2_buf_type buf_type; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + buf_type = type; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_STREAMOFF, &buf_type); + return rc; +} + +int exynos_v4l2_streamoff_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_streamoff(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE); +} + +int exynos_v4l2_streamoff_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_streamoff(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT); +} + +int exynos_v4l2_g_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int *width, int *height, int *fmt) +{ + struct v4l2_format format; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + format.type = type; + format.fmt.pix.field = V4L2_FIELD_NONE; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_FMT, &format); + if (rc < 0) + return rc; + + if (width != NULL) + *width = format.fmt.pix.width; + if (height != NULL) + *height = format.fmt.pix.height; + if (fmt != NULL) + *fmt = format.fmt.pix.pixelformat; + + return 0; +} + +int exynos_v4l2_g_fmt_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int *width, int *height, int *fmt) +{ + return exynos_v4l2_g_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + width, height, fmt); +} + +int exynos_v4l2_g_fmt_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int *width, int *height, int *fmt) +{ + return exynos_v4l2_g_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + width, height, fmt); +} + +int exynos_v4l2_s_fmt_pix(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int width, int height, int fmt, int field, + int priv) +{ + struct v4l2_format format; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + memset(&format, 0, sizeof(format)); + format.type = type; + format.fmt.pix.width = width; + format.fmt.pix.height = height; + format.fmt.pix.pixelformat = fmt; + format.fmt.pix.field = field; + format.fmt.pix.priv = priv; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FMT, &format); + return rc; + + return 0; +} + +int exynos_v4l2_s_fmt_pix_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int width, int height, int fmt, int priv) +{ + return exynos_v4l2_s_fmt_pix(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + width, height, fmt, V4L2_FIELD_NONE, priv); +} + +int exynos_v4l2_s_fmt_pix_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int width, int height, int fmt, int priv) +{ + return exynos_v4l2_s_fmt_pix(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + width, height, fmt, V4L2_FIELD_NONE, priv); +} + +int exynos_v4l2_s_fmt_win(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height) +{ + struct v4l2_format format; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + memset(&format, 0, sizeof(format)); + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + format.fmt.win.w.left = left; + format.fmt.win.w.top = top; + format.fmt.win.w.width = width; + format.fmt.win.w.height = height; + + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FMT, &format); + return rc; +} + +int exynos_v4l2_enum_fmt(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int fmt) +{ + struct v4l2_fmtdesc fmtdesc; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + fmtdesc.type = type; + fmtdesc.index = 0; + + do { + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_ENUM_FMT, &fmtdesc); + if (rc < 0) + return rc; + + if (fmtdesc.pixelformat == (unsigned int) fmt) + return 0; + + fmtdesc.index++; + } while (rc >= 0); + + return -1; +} + +int exynos_v4l2_enum_fmt_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int fmt) +{ + return exynos_v4l2_enum_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + fmt); +} + +int exynos_v4l2_enum_fmt_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int fmt) +{ + return exynos_v4l2_enum_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + fmt); +} + +int exynos_v4l2_enum_input(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int id) +{ + struct v4l2_input input; + int rc; + + if (exynos_camera == NULL || id < 0) + return -EINVAL; + + input.index = id; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_ENUMINPUT, &input); + if (rc < 0) + return rc; + + if (input.name[0] == '\0') + return -1; + + return 0; +} + +int exynos_v4l2_s_input(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id) +{ + struct v4l2_input input; + int rc; + + if (exynos_camera == NULL || id < 0) + return -EINVAL; + + input.index = id; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_INPUT, &input); + return rc; +} + +int exynos_v4l2_g_ext_ctrls(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_ext_control *control, int count) +{ + struct v4l2_ext_controls controls; + int rc; + + if (exynos_camera == NULL || control == NULL) + return -EINVAL; + + memset(&controls, 0, sizeof(controls)); + controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; + controls.count = count; + controls.controls = control; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_EXT_CTRLS, &controls); + return rc; +} + +int exynos_v4l2_g_ctrl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id, int *value) +{ + struct v4l2_control control; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + control.id = id; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_CTRL, &control); + if (rc < 0) + return rc; + + if (value != NULL) + *value = control.value; + + return 0; +} + +int exynos_v4l2_s_ctrl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id, int value) +{ + struct v4l2_control control; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + control.id = id; + control.value = value; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_CTRL, &control); + if (rc < 0) + return rc; + + return control.value; +} + +int exynos_v4l2_s_parm(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, struct v4l2_streamparm *streamparm) +{ + int rc; + + if (exynos_camera == NULL || streamparm == NULL) + return -EINVAL; + + streamparm->type = type; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_PARM, streamparm); + return rc; +} + +int exynos_v4l2_s_parm_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_streamparm *streamparm) +{ + return exynos_v4l2_s_parm(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + streamparm); +} + +int exynos_v4l2_s_parm_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_streamparm *streamparm) +{ + return exynos_v4l2_s_parm(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + streamparm); +} + +int exynos_v4l2_s_crop(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int left, int top, int width, int height) +{ + struct v4l2_crop crop; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + crop.type = type; + crop.c.left = left; + crop.c.top = top; + crop.c.width = width; + crop.c.height = height; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_CROP, &crop); + return rc; +} + +int exynos_v4l2_s_crop_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height) +{ + return exynos_v4l2_s_crop(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + left, top, width, height); +} + +int exynos_v4l2_s_crop_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height) +{ + return exynos_v4l2_s_crop(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + left, top, width, height); +} + +int exynos_v4l2_g_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + void **base, int *width, int *height, int *fmt) +{ + struct v4l2_framebuffer framebuffer; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_FBUF, &framebuffer); + if (rc < 0) + return rc; + + if (base != NULL) + *base = framebuffer.base; + if (width != NULL) + *width = framebuffer.fmt.width; + if (height != NULL) + *height = framebuffer.fmt.height; + if (fmt != NULL) + *fmt = framebuffer.fmt.pixelformat; + + return 0; +} + +int exynos_v4l2_s_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + void *base, int width, int height, int fmt) +{ + struct v4l2_framebuffer framebuffer; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + memset(&framebuffer, 0, sizeof(framebuffer)); + framebuffer.base = base; + framebuffer.fmt.width = width; + framebuffer.fmt.height = height; + framebuffer.fmt.pixelformat = fmt; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FBUF, &framebuffer); + return rc; +} diff --git a/camera/exynos_v4l2_output.c b/camera/exynos_v4l2_output.c new file mode 100644 index 0000000..0aa968a --- /dev/null +++ b/camera/exynos_v4l2_output.c @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define LOG_TAG "exynos_v4l2_output" +#include + +#include "exynos_camera.h" + +int exynos_v4l2_output_start(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output) +{ + int width, height, format; + int buffer_width, buffer_height, buffer_format; + camera_memory_t *memory = NULL; + int memory_address, memory_size; +#ifdef EXYNOS_ION + int memory_ion_fd = -1; +#endif + int buffers_count, buffer_length; + int v4l2_id; + int value; + int fd; + int rc; + int i; + + if (exynos_camera == NULL || output == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (output->enabled) { + ALOGE("Output was already started"); + return -1; + } + + width = output->width; + height = output->height; + format = output->format; + + buffer_width = output->buffer_width; + buffer_height = output->buffer_height; + buffer_format = output->buffer_format; + + v4l2_id = output->v4l2_id; + + buffers_count = output->buffers_count; + if (buffers_count <= 0) { + ALOGE("%s: Invalid buffers count: %d", __func__, buffers_count); + goto error; + } + + buffer_length = exynos_camera_buffer_length(width, height, format); + + rc = exynos_v4l2_open(exynos_camera, v4l2_id); + if (rc < 0) { + ALOGE("%s: Unable to open v4l2 device", __func__); + goto error; + } + + rc = exynos_v4l2_querycap_out(exynos_camera, v4l2_id); + if (rc < 0) { + ALOGE("%s: Unable to query capabilities", __func__); + goto error; + } + + rc = exynos_v4l2_g_fmt_out(exynos_camera, v4l2_id, NULL, NULL, NULL); + if (rc < 0) { + ALOGE("%s: Unable to get format", __func__); + goto error; + } + + value = 0; + rc = exynos_v4l2_g_ctrl(exynos_camera, v4l2_id, V4L2_CID_RESERVED_MEM_BASE_ADDR, &value); + if (rc < 0) { + ALOGE("%s: Unable to get address", __func__); + goto error; + } + + memory_address = value; + + value = 0; + rc = exynos_v4l2_g_ctrl(exynos_camera, v4l2_id, V4L2_CID_RESERVED_MEM_SIZE, &value); + if (rc < 0) { + ALOGE("%s: Unable to get size", __func__); + goto error; + } + + memory_size = value * 1024; + + value = 0; + rc = exynos_v4l2_g_ctrl(exynos_camera, v4l2_id, V4L2_CID_FIMC_VERSION, &value); + if (rc < 0) { + ALOGE("%s: Unable to get fimc version", __func__); + goto error; + } + + rc = exynos_v4l2_s_ctrl(exynos_camera, v4l2_id, V4L2_CID_OVLY_MODE, FIMC_OVLY_NONE_MULTI_BUF); + if (rc < 0) { + ALOGE("%s: Unable to set overlay mode", __func__); + goto error; + } + + rc = exynos_v4l2_s_fmt_pix_out(exynos_camera, v4l2_id, buffer_width, buffer_height, buffer_format, 0); + if (rc < 0) { + ALOGE("%s: Unable to set output pixel format!", __func__); + goto error; + } + + rc = exynos_v4l2_s_crop_out(exynos_camera, v4l2_id, 0, 0, buffer_width, buffer_height); + if (rc < 0) { + ALOGE("%s: Unable to crop", __func__); + goto error; + } + + rc = exynos_v4l2_reqbufs_out(exynos_camera, v4l2_id, 1); + if (rc < 0) { + ALOGE("%s: Unable to request buffers", __func__); + goto error; + } + + if (memory_address != 0 && memory_address != (int) 0xffffffff && memory_size >= buffer_length) { + for (i = buffers_count; i > 0; i--) { + if (buffer_length * i < memory_size) + break; + } + + // This should never happen + if (i == 0) + goto error; + + buffers_count = i; + ALOGD("Found %d buffers available for output!", buffers_count); + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + fd = exynos_v4l2_fd(exynos_camera, v4l2_id); + if (fd < 0) { + ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, v4l2_id); + goto error; + } + + memory = exynos_camera->callbacks.request_memory(fd, buffer_length, buffers_count, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + } else { +#ifdef EXYNOS_ION + memory_ion_fd = exynos_ion_alloc(exynos_camera, buffers_count * buffer_length); + if (memory_ion_fd < 0) { + ALOGE("%s: Unable to alloc ION memory", __func__); + goto error; + } + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(memory_ion_fd, buffer_length, buffers_count, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + memory_address = exynos_ion_phys(exynos_camera, memory_ion_fd); +#else + ALOGE("%s: Unable to find memory", __func__); + goto error; +#endif + } + + output->memory = memory; + output->memory_address = memory_address; +#ifdef EXYNOS_ION + output->memory_ion_fd = memory_ion_fd; +#endif + output->memory_index = 0; + output->buffers_count = buffers_count; + output->buffer_length = buffer_length; + + output->enabled = 1; + + rc = 0; + goto complete; + +error: + if (memory != NULL && memory->release != NULL) { + memory->release(memory); + output->memory = NULL; + } + +#ifdef EXYNOS_ION + if (memory_ion_fd >= 0) + exynos_ion_free(exynos_camera, memory_ion_fd); +#endif + + exynos_v4l2_close(exynos_camera, v4l2_id); + + rc = -1; + +complete: + return rc; +} + +void exynos_v4l2_output_stop(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output) +{ + int v4l2_id; + int rc; + + if (exynos_camera == NULL || output == NULL) + return; + +// ALOGD("%s()", __func__); + + if (!output->enabled) { + ALOGE("Output was already stopped"); + return; + } + + v4l2_id = output->v4l2_id; + + rc = exynos_v4l2_reqbufs_out(exynos_camera, v4l2_id, 0); + if (rc < 0) + ALOGE("%s: Unable to request buffers", __func__); + + if (output->memory != NULL && output->memory->release != NULL) { + output->memory->release(output->memory); + output->memory = NULL; + } + +#ifdef EXYNOS_ION + if (output->memory_ion_fd >= 0) { + exynos_ion_free(exynos_camera, output->memory_ion_fd); + output->memory_ion_fd = -1; + } +#endif + + exynos_v4l2_close(exynos_camera, v4l2_id); + + output->enabled = 0; +} + +int exynos_v4l2_output(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output, int buffer_address) +{ + struct fimc_buf fimc_buffer; + void *fb_base; + int width, height, format; + int buffer_width, buffer_height, buffer_format; + int buffer_length; + int address; + int v4l2_id; + int rc; + + if (exynos_camera == NULL || output == NULL) + return -EINVAL; + +// ALOGD("%s()", __func__); + + if (!output->enabled) { + ALOGE("Output was not started"); + return -1; + } + + width = output->width; + height = output->height; + format = output->format; + + buffer_width = output->buffer_width; + buffer_height = output->buffer_height; + buffer_format = output->buffer_format; + + buffer_length = output->buffer_length; + v4l2_id = output->v4l2_id; + + rc = exynos_v4l2_g_fbuf(exynos_camera, v4l2_id, &fb_base, NULL, NULL, NULL); + if (rc < 0) { + ALOGE("%s: Unable to get fbuf", __func__); + goto error; + } + + rc = exynos_v4l2_s_fbuf(exynos_camera, v4l2_id, fb_base, width, height, format); + if (rc < 0) { + ALOGE("%s: Unable to set fbuf", __func__); + goto error; + } + + memset(&fimc_buffer, 0, sizeof(fimc_buffer)); + + address = output->memory_address + buffer_length * output->memory_index; + + exynos_camera_yuv_planes(width, height, format, address, (int *) &fimc_buffer.base[0], (int *) &fimc_buffer.base[1], (int *) &fimc_buffer.base[2]); + + rc = exynos_v4l2_s_ctrl(exynos_camera, v4l2_id, V4L2_CID_DST_INFO, (int) &fimc_buffer); + if (rc < 0) { + ALOGE("%s: Unable to set dst info", __func__); + goto error; + } + + rc = exynos_v4l2_s_fmt_win(exynos_camera, v4l2_id, 0, 0, width, height); + if (rc < 0) { + ALOGE("%s: Unable to set overlay win", __func__); + goto error; + } + + rc = exynos_v4l2_streamon_out(exynos_camera, v4l2_id); + if (rc < 0) { + ALOGE("%s: Unable to start stream", __func__); + goto error; + } + + memset(&fimc_buffer, 0, sizeof(fimc_buffer)); + + exynos_camera_yuv_planes(buffer_width, buffer_height, buffer_format, buffer_address, (int *) &fimc_buffer.base[0], (int *) &fimc_buffer.base[1], (int *) &fimc_buffer.base[2]); + + rc = exynos_v4l2_qbuf_out(exynos_camera, v4l2_id, 0, (unsigned long) &fimc_buffer); + if (rc < 0) { + ALOGE("%s: Unable to queue buffer", __func__); + goto error; + } + + rc = exynos_v4l2_dqbuf_out(exynos_camera, v4l2_id); + if (rc < 0) { + ALOGE("%s: Unable to dequeue buffer", __func__); + goto error; + } + + rc = exynos_v4l2_streamoff_out(exynos_camera, v4l2_id); + if (rc < 0) { + ALOGE("%s: Unable to stop stream", __func__); + goto error; + } + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + return rc; +} + +int exynos_v4l2_output_release(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output) +{ + int buffers_count; + int memory_index; + + if (exynos_camera == NULL || output == NULL) + return -EINVAL; + +// ALOGD("%s()", __func__); + + buffers_count = output->buffers_count; + memory_index = output->memory_index; + + memory_index++; + output->memory_index = memory_index % buffers_count; + + return 0; +} diff --git a/camera/include/linux/fimc.h b/camera/include/linux/fimc.h new file mode 100644 index 0000000..40deab0 --- /dev/null +++ b/camera/include/linux/fimc.h @@ -0,0 +1,381 @@ +/* linux/drivers/media/video/samsung/fimc/fimc.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Header file for Samsung Camera Interface (FIMC) driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + + +#ifndef __FIMC_H +#define __FIMC_H __FILE__ + +typedef unsigned int dma_addr_t; +typedef __u32 u32; +typedef __s32 s32; + +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER) +#include +#endif +#include +#include +#include +#endif + +#ifdef CONFIG_PM_RUNTIME +#include +#endif + +#define FIMC_NAME "s3c-fimc" +#define FIMC_CMA_NAME "fimc" + +#define FIMC_CORE_CLK "sclk_fimc" +#define FIMC_CLK_RATE 166750000 +#define EXYNOS_BUSFREQ_NAME "exynos-busfreq" + +#if defined(CONFIG_ARCH_EXYNOS4) +#define FIMC_DEVICES 4 +#define FIMC_PHYBUFS 32 +#define FIMC_MAXCAMS 7 +#else +#define FIMC_DEVICES 3 +#define FIMC_PHYBUFS 4 +#define FIMC_MAXCAMS 5 +#endif + +#define FIMC_SUBDEVS 3 +#define FIMC_OUTBUFS 3 +#define FIMC_INQUEUES 10 +#define FIMC_MAX_CTXS 4 +#define FIMC_TPID 3 +#define FIMC_CAPBUFS 32 +#define FIMC_ONESHOT_TIMEOUT 200 +#define FIMC_DQUEUE_TIMEOUT 1000 + +#define FIMC_FIFOOFF_CNT 1000000 /* Sufficiently big value for stop */ + +#define FORMAT_FLAGS_PACKED 0x1 +#define FORMAT_FLAGS_PLANAR 0x2 + +#define FIMC_ADDR_Y 0 +#define FIMC_ADDR_CB 1 +#define FIMC_ADDR_CR 2 + +#define FIMC_HD_WIDTH 1280 +#define FIMC_HD_HEIGHT 720 + +#define FIMC_FHD_WIDTH 1920 +#define FIMC_FHD_HEIGHT 1080 + +#define FIMC_MMAP_IDX -1 +#define FIMC_USERPTR_IDX -2 + +#define FIMC_HCLK 0 +#define FIMC_SCLK 1 +#define CSI_CH_0 0 +#define CSI_CH_1 1 +#if defined(CONFIG_VIDEO_FIMC_FIFO) +#define FIMC_OVLY_MODE FIMC_OVLY_FIFO +#elif defined(CONFIG_VIDEO_FIMC_DMA_AUTO) +#define FIMC_OVLY_MODE FIMC_OVLY_DMA_AUTO +#endif + +#define PINGPONG_2ADDR_MODE +#if defined(PINGPONG_2ADDR_MODE) +#define FIMC_PINGPONG 2 +#endif + +#define check_bit(data, loc) ((data) & (0x1<<(loc))) +#define FRAME_SEQ 0xf + +#define fimc_cam_use ((pdata->use_cam) ? 1 : 0) + +#define L2_FLUSH_ALL SZ_1M +#define L1_FLUSH_ALL SZ_64K + +/* + * ENUMERATIONS +*/ +enum fimc_status { + FIMC_READY_OFF = 0x00, + FIMC_STREAMOFF = 0x01, + FIMC_READY_ON = 0x02, + FIMC_STREAMON = 0x03, + FIMC_STREAMON_IDLE = 0x04, /* oneshot mode */ + FIMC_OFF_SLEEP = 0x05, + FIMC_ON_SLEEP = 0x06, + FIMC_ON_IDLE_SLEEP = 0x07, /* oneshot mode */ + FIMC_READY_RESUME = 0x08, + FIMC_BUFFER_STOP = 0x09, + FIMC_BUFFER_START = 0x0A, +}; + +enum fimc_fifo_state { + FIFO_CLOSE, + FIFO_SLEEP, +}; + +enum fimc_fimd_state { + FIMD_OFF, + FIMD_ON, +}; + +enum fimc_rot_flip { + FIMC_XFLIP = 0x01, + FIMC_YFLIP = 0x02, + FIMC_ROT = 0x10, +}; + +enum fimc_input { + FIMC_SRC_CAM, + FIMC_SRC_MSDMA, +}; + +enum fimc_overlay_mode { + FIMC_OVLY_NOT_FIXED = 0x0, /* Overlay mode isn't fixed. */ + FIMC_OVLY_FIFO = 0x1, /* Non-destructive Overlay with FIFO */ + FIMC_OVLY_DMA_AUTO = 0x2, /* Non-destructive Overlay with DMA */ + FIMC_OVLY_DMA_MANUAL = 0x3, /* Non-destructive Overlay with DMA */ + FIMC_OVLY_NONE_SINGLE_BUF = 0x4, /* Destructive Overlay with DMA single destination buffer */ + FIMC_OVLY_NONE_MULTI_BUF = 0x5, /* Destructive Overlay with DMA multiple dstination buffer */ +}; + +enum fimc_autoload { + FIMC_AUTO_LOAD, + FIMC_ONE_SHOT, +}; + +enum fimc_log { + FIMC_LOG_DEBUG = 0x1000, + FIMC_LOG_INFO_L2 = 0x0200, + FIMC_LOG_INFO_L1 = 0x0100, + FIMC_LOG_WARN = 0x0010, + FIMC_LOG_ERR = 0x0001, +}; + +enum fimc_range { + FIMC_RANGE_NARROW = 0x0, + FIMC_RANGE_WIDE = 0x1, +}; + +enum fimc_pixel_format_type{ + FIMC_RGB, + FIMC_YUV420, + FIMC_YUV422, + FIMC_YUV444, +}; + +enum fimc_framecnt_seq { + FIMC_FRAMECNT_SEQ_DISABLE, + FIMC_FRAMECNT_SEQ_ENABLE, +}; + +enum fimc_sysmmu_flag { + FIMC_SYSMMU_OFF, + FIMC_SYSMMU_ON, +}; + +enum fimc_id { + FIMC0 = 0x0, + FIMC1 = 0x1, + FIMC2 = 0x2, + FIMC3 = 0x3, +}; + +enum fimc_power_status { + FIMC_POWER_OFF, + FIMC_POWER_ON, + FIMC_POWER_SUSPEND, +}; + +enum cam_mclk_status { + CAM_MCLK_OFF, + CAM_MCLK_ON, +}; + +/* + * STRUCTURES +*/ + +/* for reserved memory */ +struct fimc_meminfo { + dma_addr_t base; /* buffer base */ + size_t size; /* total length */ + dma_addr_t curr; /* current addr */ + dma_addr_t vaddr_base; /* buffer base */ + dma_addr_t vaddr_curr; /* current addr */ +}; + +struct fimc_buf { + dma_addr_t base[3]; + size_t length[3]; +}; + +struct fimc_overlay_buf { + u32 vir_addr[3]; + size_t size[3]; + u32 phy_addr[3]; +}; + +struct fimc_overlay { + enum fimc_overlay_mode mode; + struct fimc_overlay_buf buf; + s32 req_idx; +}; + +/* for output overlay device */ +struct fimc_idx { + int ctx; + int idx; +}; + +struct fimc_ctx_idx { + struct fimc_idx prev; + struct fimc_idx active; + struct fimc_idx next; +}; + +/* scaler abstraction: local use recommended */ +struct fimc_scaler { + u32 bypass; + u32 hfactor; + u32 vfactor; + u32 pre_hratio; + u32 pre_vratio; + u32 pre_dst_width; + u32 pre_dst_height; + u32 scaleup_h; + u32 scaleup_v; + u32 main_hratio; + u32 main_vratio; + u32 real_width; + u32 real_height; + u32 shfactor; + u32 skipline; +}; + +struct s3cfb_user_window { + int x; + int y; +}; + +enum s3cfb_data_path_t { + DATA_PATH_FIFO = 0, + DATA_PATH_DMA = 1, + DATA_PATH_IPC = 2, +}; + +enum s3cfb_mem_owner_t { + DMA_MEM_NONE = 0, + DMA_MEM_FIMD = 1, + DMA_MEM_OTHER = 2, +}; +#define S3CFB_WIN_OFF_ALL _IO('F', 202) +#define S3CFB_WIN_POSITION _IOW('F', 203, struct s3cfb_user_window) +#define S3CFB_GET_LCD_WIDTH _IOR('F', 302, int) +#define S3CFB_GET_LCD_HEIGHT _IOR('F', 303, int) +#define S3CFB_SET_WRITEBACK _IOW('F', 304, u32) +#define S3CFB_SET_WIN_ON _IOW('F', 305, u32) +#define S3CFB_SET_WIN_OFF _IOW('F', 306, u32) +#define S3CFB_SET_WIN_PATH _IOW('F', 307, enum s3cfb_data_path_t) +#define S3CFB_SET_WIN_ADDR _IOW('F', 308, unsigned long) +#define S3CFB_SET_WIN_MEM _IOW('F', 309, enum s3cfb_mem_owner_t) +/* ------------------------------------------------------------------------ */ + +struct fimc_fbinfo { + struct fb_fix_screeninfo *fix; + struct fb_var_screeninfo *var; + int lcd_hres; + int lcd_vres; + u32 is_enable; + /* lcd fifo control */ + + int (*open_fifo)(int id, int ch, int (*do_priv)(void *), void *param); + int (*close_fifo)(int id, int (*do_priv)(void *), void *param); +}; + +struct fimc_limit { + u32 pre_dst_w; + u32 bypass_w; + u32 trg_h_no_rot; + u32 trg_h_rot; + u32 real_w_no_rot; + u32 real_h_rot; +}; + +enum FIMC_EFFECT_FIN { + FIMC_EFFECT_FIN_BYPASS = 0, + FIMC_EFFECT_FIN_ARBITRARY_CBCR, + FIMC_EFFECT_FIN_NEGATIVE, + FIMC_EFFECT_FIN_ART_FREEZE, + FIMC_EFFECT_FIN_EMBOSSING, + FIMC_EFFECT_FIN_SILHOUETTE, +}; + + +struct fimc_effect { + int ie_on; + int ie_after_sc; + enum FIMC_EFFECT_FIN fin; + int pat_cb; + int pat_cr; +}; + +/* debug macro */ +#define FIMC_LOG_DEFAULT (FIMC_LOG_WARN | FIMC_LOG_ERR) + +#define FIMC_DEBUG(fmt, ...) \ + do { \ + printk(KERN_DEBUG FIMC_NAME "%d: " \ + fmt, ctrl->id, ##__VA_ARGS__); \ + } while (0) + +#define FIMC_INFO_L2(fmt, ...) \ + do { \ + printk(KERN_INFO FIMC_NAME "%d: " \ + fmt, ctrl->id, ##__VA_ARGS__); \ + } while (0) + +#define FIMC_INFO_L1(fmt, ...) \ + do { \ + printk(KERN_INFO FIMC_NAME "%d: " \ + fmt, ctrl->id, ##__VA_ARGS__); \ + } while (0) + +#define FIMC_WARN(fmt, ...) \ + do { \ + printk(KERN_WARNING FIMC_NAME "%d: " \ + fmt, ctrl->id, ##__VA_ARGS__); \ + } while (0) + + +#define FIMC_ERROR(fmt, ...) \ + do { \ + printk(KERN_ERR FIMC_NAME "%d: " \ + fmt, ctrl->id, ##__VA_ARGS__); \ + } while (0) + + +#define fimc_dbg(fmt, ...) FIMC_DEBUG(fmt, ##__VA_ARGS__) +#define fimc_info2(fmt, ...) FIMC_INFO_L2(fmt, ##__VA_ARGS__) +#define fimc_info1(fmt, ...) FIMC_INFO_L1(fmt, ##__VA_ARGS__) +#define fimc_warn(fmt, ...) FIMC_WARN(fmt, ##__VA_ARGS__) +#define fimc_err(fmt, ...) FIMC_ERROR(fmt, ##__VA_ARGS__) + +#endif /* __FIMC_H */ diff --git a/camera/include/linux/ion.h b/camera/include/linux/ion.h new file mode 100644 index 0000000..29dba57 --- /dev/null +++ b/camera/include/linux/ion.h @@ -0,0 +1,449 @@ +/* + * include/linux/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_ION_H +#define _LINUX_ION_H + +#include + +#define CONFIG_ION_EXYNOS + +/* This should be removed some day when phys_addr_t's are fully + plumbed in the kernel, and all instances of ion_phys_addr_t should + be converted to phys_addr_t. For the time being many kernel interfaces + do not accept phys_addr_t's that would have to */ +#define ion_phys_addr_t unsigned long + +struct ion_handle; +/** + * enum ion_heap_types - list of all possible types of heaps + * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc + * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc + * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved + * carveout heap, allocations are physically + * contiguous + * @ION_HEAP_END: helper for iterating over heaps + */ +enum ion_heap_type { + ION_HEAP_TYPE_SYSTEM, + ION_HEAP_TYPE_SYSTEM_CONTIG, + ION_HEAP_TYPE_CARVEOUT, + ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always + are at the end of this enum */ +#ifdef CONFIG_ION_EXYNOS + ION_HEAP_TYPE_EXYNOS_CONTIG, + ION_HEAP_TYPE_EXYNOS, + ION_HEAP_TYPE_EXYNOS_USER, +#endif + ION_NUM_HEAPS, +}; + +#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM) +#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG) +#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT) + +#ifdef CONFIG_ION_EXYNOS +#define ION_HEAP_EXYNOS_MASK (1 << ION_HEAP_TYPE_EXYNOS) +#define ION_HEAP_EXYNOS_CONTIG_MASK (1 << ION_HEAP_TYPE_EXYNOS_CONTIG) +#define ION_HEAP_EXYNOS_USER_MASK (1 << ION_HEAP_TYPE_EXYNOS_USER) +#define ION_EXYNOS_NONCACHE_MASK (1 << (BITS_PER_LONG - 2)) +#define ION_EXYNOS_WRITE_MASK (1 << (BITS_PER_LONG - 1)) +#endif + +#ifdef __KERNEL__ +struct ion_device; +struct ion_heap; +struct ion_mapper; +struct ion_client; +struct ion_buffer; + +/** + * struct ion_platform_heap - defines a heap in the given platform + * @type: type of the heap from ion_heap_type enum + * @id: unique identifier for heap. When allocating (lower numbers + * will be allocated from first) + * @name: used for debug purposes + * @base: base address of heap in physical memory if applicable + * @size: size of the heap in bytes if applicable + * + * Provided by the board file. + */ +struct ion_platform_heap { + enum ion_heap_type type; + unsigned int id; + const char *name; + ion_phys_addr_t base; + size_t size; +}; + +/** + * struct ion_platform_data - array of platform heaps passed from board file + * @nr: number of structures in the array + * @heaps: array of platform_heap structions + * + * Provided by the board file in the form of platform data to a platform device. + */ +struct ion_platform_data { + int nr; + struct ion_platform_heap heaps[]; +}; + +/** + * ion_client_create() - allocate a client and returns it + * @dev: the global ion device + * @heap_mask: mask of heaps this client can allocate from + * @name: used for debugging + */ +struct ion_client *ion_client_create(struct ion_device *dev, + unsigned int heap_mask, const char *name); + +/** + * ion_client_destroy() - free's a client and all it's handles + * @client: the client + * + * Free the provided client and all it's resources including + * any handles it is holding. + */ +void ion_client_destroy(struct ion_client *client); + +/** + * ion_get_client() - obtain a user client from file descriptor from user + * @fd: the user client created by the request from user. This is + * passed from user. + * + * This function is requested by the device drivers that implement V4L2 and VB2 + * interfaces. Those device drivers just obtains virtual address of a buffer + * even though it is allocated and mapped by ION. While they can retrieve the + * handle of the buffer, they are unable to access it because they do not know + * what client the handle belongs to. + * Note that the client obtained by this function is not released until + * ion_put_client() is called and the client is given. + */ +struct ion_client *ion_get_user_client(unsigned int fd_client); + +/** + * ion_put_client() - release the user client obtained by ion_get_client() + * @client - The user client to release. + */ +void ion_put_user_client(struct ion_client *user_client); + +/** + * ion_alloc - allocate ion memory + * @client: the client + * @len: size of the allocation + * @align: requested allocation alignment, lots of hardware blocks have + * alignment requirements of some kind + * @flags: mask of heaps to allocate from, if multiple bits are set + * heaps will be tried in order from lowest to highest order bit + * + * Allocate memory in one of the heaps provided in heap mask and return + * an opaque handle to it. + */ +struct ion_handle *ion_alloc(struct ion_client *client, size_t len, + size_t align, unsigned int flags); + +/** + * ion_free - free a handle + * @client: the client + * @handle: the handle to free + * + * Free the provided handle. + */ +void ion_free(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_phys - returns the physical address and len of a handle + * @client: the client + * @handle: the handle + * @addr: a pointer to put the address in + * @len: a pointer to put the length in + * + * This function queries the heap for a particular handle to get the + * handle's physical address. It't output is only correct if + * a heap returns physically contiguous memory -- in other cases + * this api should not be implemented -- ion_map_dma should be used + * instead. Returns -EINVAL if the handle is invalid. This has + * no implications on the reference counting of the handle -- + * the returned value may not be valid if the caller is not + * holding a reference. + */ +int ion_phys(struct ion_client *client, struct ion_handle *handle, + ion_phys_addr_t *addr, size_t *len); + +/** + * ion_map_kernel - create mapping for the given handle + * @client: the client + * @handle: handle to map + * + * Map the given handle into the kernel and return a kernel address that + * can be used to access this address. + */ +void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_unmap_kernel() - destroy a kernel mapping for a handle + * @client: the client + * @handle: handle to unmap + */ +void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_map_dma - create a dma mapping for a given handle + * @client: the client + * @handle: handle to map + * + * Return an sglist describing the given handle + */ +struct scatterlist *ion_map_dma(struct ion_client *client, + struct ion_handle *handle); + +/** + * ion_unmap_dma() - destroy a dma mapping for a handle + * @client: the client + * @handle: handle to unmap + */ +void ion_unmap_dma(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_share() - given a handle, obtain a buffer to pass to other clients + * @client: the client + * @handle: the handle to share + * + * Given a handle, return a buffer, which exists in a global name + * space, and can be passed to other clients. Should be passed into ion_import + * to obtain a new handle for this buffer. + * + * NOTE: This function does do not an extra reference. The burden is on the + * caller to make sure the buffer doesn't go away while it's being passed to + * another client. That is, ion_free should not be called on this handle until + * the buffer has been imported into the other client. + */ +struct ion_buffer *ion_share(struct ion_client *client, + struct ion_handle *handle); + +/** + * ion_import() - given an buffer in another client, import it + * @client: this blocks client + * @buffer: the buffer to import (as obtained from ion_share) + * + * Given a buffer, add it to the client and return the handle to use to refer + * to it further. This is called to share a handle from one kernel client to + * another. + */ +struct ion_handle *ion_import(struct ion_client *client, + struct ion_buffer *buffer); + +/** + * ion_share_fd() - given a handle, obtain a buffer(fd) to pass to userspace + * @client: the client + * @handle: the handle to share + * + * Given a handle, return a fd of a buffer which can be passed to userspace. + * Should be passed into userspace or ion_import_fd to obtain a new handle for + * this buffer. + */ +int ion_share_fd(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_import_fd() - given an fd obtained via ION_IOC_SHARE ioctl, import it + * @client: this blocks client + * @fd: the fd + * + * A helper function for drivers that will be recieving ion buffers shared + * with them from userspace. These buffers are represented by a file + * descriptor obtained as the return from the ION_IOC_SHARE ioctl. + * This function coverts that fd into the underlying buffer, and returns + * the handle to use to refer to it further. + */ +struct ion_handle *ion_import_fd(struct ion_client *client, int fd); + +/** + * ion_import_uva() - given a virtual address from user, that is mmapped on an + * fd obtained via ION_IOCTL_SHARE ioctl, import it + * @client: this blocks client + * @uva: virtual address in userspace. + * @offset: How many bytes are distant from the beginning of the ION buffer + * + * A helper function for drivers that will be recieving ion buffers shared + * with them from userspace. These buffers are represented by a virtual + * address that is mmaped on a file descriptor obtained as the return from the + * ION_IOC_SHARE ioctl. + * This function does same job with ion_import_fd(). + */ +struct ion_handle *ion_import_uva(struct ion_client *client, unsigned long uva, + off_t *offset); + +#ifdef CONFIG_ION_EXYNOS +struct ion_handle *ion_exynos_get_user_pages(struct ion_client *client, + unsigned long uvaddr, size_t len, unsigned int flags); +#else +#include +static inline struct ion_handle *ion_exynos_get_user_pages( + struct ion_client *client, unsigned long uvaddr, + size_t len, unsigned int flags) +{ + return ERR_PTR(-ENOSYS); +} +#endif + +#endif /* __KERNEL__ */ + +/** + * DOC: Ion Userspace API + * + * create a client by opening /dev/ion + * most operations handled via following ioctls + * + */ + +/** + * struct ion_allocation_data - metadata passed from userspace for allocations + * @len: size of the allocation + * @align: required alignment of the allocation + * @flags: flags passed to heap + * @handle: pointer that will be populated with a cookie to use to refer + * to this allocation + * + * Provided by userspace as an argument to the ioctl + */ +struct ion_allocation_data { + size_t len; + size_t align; + unsigned int flags; + struct ion_handle *handle; +}; + +/** + * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair + * @handle: a handle + * @fd: a file descriptor representing that handle + * + * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with + * the handle returned from ion alloc, and the kernel returns the file + * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace + * provides the file descriptor and the kernel returns the handle. + */ +struct ion_fd_data { + struct ion_handle *handle; + int fd; +}; + +/** + * struct ion_handle_data - a handle passed to/from the kernel + * @handle: a handle + */ +struct ion_handle_data { + struct ion_handle *handle; +}; + +/** + * struct ion_custom_data - metadata passed to/from userspace for a custom ioctl + * @cmd: the custom ioctl function to call + * @arg: additional data to pass to the custom ioctl, typically a user + * pointer to a predefined structure + * + * This works just like the regular cmd and arg fields of an ioctl. + */ +struct ion_custom_data { + unsigned int cmd; + unsigned long arg; +}; + +enum ION_MSYNC_TYPE { + IMSYNC_DEV_TO_READ = 0, + IMSYNC_DEV_TO_WRITE = 1, + IMSYNC_DEV_TO_RW = 2, + IMSYNC_BUF_TYPES_MASK = 3, + IMSYNC_BUF_TYPES_NUM = 4, + IMSYNC_SYNC_FOR_DEV = 0x10000, + IMSYNC_SYNC_FOR_CPU = 0x20000, +}; + +struct ion_msync_data { + enum ION_MSYNC_TYPE dir; + int fd_buffer; + size_t size; + off_t offset; +}; + +struct ion_phys_data { + int fd_buffer; + ion_phys_addr_t phys; + size_t size; +}; + +enum ION_EXYNOS_CUSTOM_CMD { + ION_EXYNOS_CUSTOM_MSYNC, + ION_EXYNOS_CUSTOM_PHYS +}; + +#define ION_IOC_MAGIC 'I' + +/** + * DOC: ION_IOC_ALLOC - allocate memory + * + * Takes an ion_allocation_data struct and returns it with the handle field + * populated with the opaque handle for the allocation. + */ +#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ + struct ion_allocation_data) + +/** + * DOC: ION_IOC_FREE - free memory + * + * Takes an ion_handle_data struct and frees the handle. + */ +#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) + +/** + * DOC: ION_IOC_MAP - get a file descriptor to mmap + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be used as an argument to mmap. + */ +#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) + +/** + * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be passed to another process. The corresponding opaque handle can + * be retrieved via ION_IOC_IMPORT. + */ +#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) + +/** + * DOC: ION_IOC_IMPORT - imports a shared file descriptor + * + * Takes an ion_fd_data struct with the fd field populated with a valid file + * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle + * filed set to the corresponding opaque handle. + */ +#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, int) + +/** + * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl + * + * Takes the argument of the architecture specific ioctl to call and + * passes appropriate userdata for that ioctl + */ +#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) + +#endif /* _LINUX_ION_H */ diff --git a/camera/include/linux/videodev2.h b/camera/include/linux/videodev2.h new file mode 100644 index 0000000..a464469 --- /dev/null +++ b/camera/include/linux/videodev2.h @@ -0,0 +1,2364 @@ +/* + * Video for Linux Two header file + * + * Copyright (C) 1999-2007 the contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Alternatively you can redistribute this file under the terms of the + * BSD license as stated below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Header file for v4l or V4L2 drivers and applications + * with public API. + * All kernel-specific stuff were moved to media/v4l2-dev.h, so + * no #if __KERNEL tests are allowed here + * + * See http://linuxtv.org for more info + * + * Author: Bill Dirks + * Justin Schoeman + * Hans Verkuil + * et al. + */ +#ifndef __LINUX_VIDEODEV2_H +#define __LINUX_VIDEODEV2_H + +#ifdef __KERNEL__ +#include /* need struct timeval */ +#else +#include +#endif +#include +#include +#include + +/* + * Common stuff for both V4L1 and V4L2 + * Moved from videodev.h + */ +#define VIDEO_MAX_FRAME 32 +#define VIDEO_MAX_PLANES 8 + +#ifndef __KERNEL__ + +/* These defines are V4L1 specific and should not be used with the V4L2 API! + They will be removed from this header in the future. */ + +#define VID_TYPE_CAPTURE 1 /* Can capture */ +#define VID_TYPE_TUNER 2 /* Can tune */ +#define VID_TYPE_TELETEXT 4 /* Does teletext */ +#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ +#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ +#define VID_TYPE_CLIPPING 32 /* Can clip */ +#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ +#define VID_TYPE_SCALES 128 /* Scalable */ +#define VID_TYPE_MONOCHROME 256 /* Monochrome only */ +#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ +#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ +#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ +#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ +#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ +#endif + +/* + * M I S C E L L A N E O U S + */ + +/* Four-character-code (FOURCC) */ +#define v4l2_fourcc(a, b, c, d)\ + ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24)) + +/* + * E N U M S + */ +enum v4l2_field { + V4L2_FIELD_ANY = 0, /* driver can choose from none, + top, bottom, interlaced + depending on whatever it thinks + is approximate ... */ + V4L2_FIELD_NONE = 1, /* this device has no fields ... */ + V4L2_FIELD_TOP = 2, /* top field only */ + V4L2_FIELD_BOTTOM = 3, /* bottom field only */ + V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ + V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one + buffer, top-bottom order */ + V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ + V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into + separate buffers */ + V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field + first and the top field is + transmitted first */ + V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field + first and the bottom field is + transmitted first */ +}; +#define V4L2_FIELD_HAS_TOP(field) \ + ((field) == V4L2_FIELD_TOP ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTTOM(field) \ + ((field) == V4L2_FIELD_BOTTOM ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTH(field) \ + ((field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) + +enum v4l2_buf_type { + V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, + V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, + V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, + V4L2_BUF_TYPE_VBI_CAPTURE = 4, + V4L2_BUF_TYPE_VBI_OUTPUT = 5, + V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, + V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, +#if 1 + /* Experimental */ + V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, +#endif + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9, + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10, + V4L2_BUF_TYPE_PRIVATE = 0x80, +}; + +#define V4L2_TYPE_IS_MULTIPLANAR(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + +#define V4L2_TYPE_IS_OUTPUT(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \ + || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \ + || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \ + || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) + +enum v4l2_tuner_type { + V4L2_TUNER_RADIO = 1, + V4L2_TUNER_ANALOG_TV = 2, + V4L2_TUNER_DIGITAL_TV = 3, +}; + +enum v4l2_memory { + V4L2_MEMORY_MMAP = 1, + V4L2_MEMORY_USERPTR = 2, + V4L2_MEMORY_OVERLAY = 3, + V4L2_MEMORY_DMABUF = 4, +}; + +/* see also http://vektor.theorem.ca/graphics/ycbcr/ */ +enum v4l2_colorspace { + /* ITU-R 601 -- broadcast NTSC/PAL */ + V4L2_COLORSPACE_SMPTE170M = 1, + + /* 1125-Line (US) HDTV */ + V4L2_COLORSPACE_SMPTE240M = 2, + + /* HD and modern captures. */ + V4L2_COLORSPACE_REC709 = 3, + + /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ + V4L2_COLORSPACE_BT878 = 4, + + /* These should be useful. Assume 601 extents. */ + V4L2_COLORSPACE_470_SYSTEM_M = 5, + V4L2_COLORSPACE_470_SYSTEM_BG = 6, + + /* I know there will be cameras that send this. So, this is + * unspecified chromaticities and full 0-255 on each of the + * Y'CbCr components + */ + V4L2_COLORSPACE_JPEG = 7, + + /* For RGB colourspaces, this is probably a good start. */ + V4L2_COLORSPACE_SRGB = 8, +}; + +enum v4l2_priority { + V4L2_PRIORITY_UNSET = 0, /* not initialized */ + V4L2_PRIORITY_BACKGROUND = 1, + V4L2_PRIORITY_INTERACTIVE = 2, + V4L2_PRIORITY_RECORD = 3, + V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE, +}; + +struct v4l2_rect { + __s32 left; + __s32 top; + __s32 width; + __s32 height; +}; + +struct v4l2_fract { + __u32 numerator; + __u32 denominator; +}; + +/* + * D R I V E R C A P A B I L I T I E S + */ +struct v4l2_capability { + __u8 driver[16]; /* i.e. "bttv" */ + __u8 card[32]; /* i.e. "Hauppauge WinTV" */ + __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ + __u32 version; /* should use KERNEL_VERSION() */ + __u32 capabilities; /* Device capabilities */ + __u32 reserved[4]; +}; + +/* Values for 'capabilities' field */ +#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ +#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ +#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ +#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ +#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ +#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ +#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ +#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ +#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ +#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ +#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ + +/* Is a video capture device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000 +/* Is a video output device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000 + +#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ +#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ +#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ +#define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */ + +#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ +#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ +#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ + +/* + * V I D E O I M A G E F O R M A T + */ +struct v4l2_pix_format { + __u32 width; + __u32 height; + __u32 pixelformat; + enum v4l2_field field; + __u32 bytesperline; /* for padding, zero if unused */ + __u32 sizeimage; + enum v4l2_colorspace colorspace; + __u32 priv; /* private data, depends on pixelformat */ +}; + +/* Pixel format FOURCC depth Description */ + +/* RGB formats */ +#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ +#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ +#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ +#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ +#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ +#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ +#define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */ +#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ +#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ +#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ +#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ + +/* Grey formats */ +#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ +#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ +#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ +#define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ +#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ + +/* Grey bit-packed formats */ +#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ + +/* Palette formats */ +#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ + +/* Luminance+Chrominance formats */ +#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */ +#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ +#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ +#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ +#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ +#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ +#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */ +#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */ +#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */ +#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */ +#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ +#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ +#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ +#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ +#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ +#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */ +#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */ + +/* two non contiguous planes - one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ + +/* three non contiguous planes - Y, Cb, Cr */ +#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */ + +/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ +#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ +#define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ +#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') /* 12 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ + /* 10bit raw bayer DPCM compressed to 8 bits */ +#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') + /* + * 10bit raw bayer, expanded to 16 bits + * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... + */ +#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ + +/* compressed formats */ +#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */ +#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */ +#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */ +#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 Multiplexed */ +#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */ +#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */ +#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */ +#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */ +#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */ +#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 ES */ +#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */ +#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */ +#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ + +/* Vendor-specific formats */ +#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ +#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ +#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ +#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ +#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ +#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ +#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ +#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */ +#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */ +#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */ +#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ +#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ +#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ +#define V4L2_PIX_FMT_JL2005BCD v4l2_fourcc('J', 'L', '2', '0') /* compressed RGGB bayer */ +#define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */ +#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ +#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ +#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ +#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ +#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ +#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ +#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ +#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ +#define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */ +/* RGB x:10:10:10 */ +#define V4L2_PIX_FMT_INTC_RGB30 v4l2_fourcc('R', 'G', 'B', '0') +#define V4L2_PIX_FMT_SE401 v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */ + +/* + * F O R M A T E N U M E R A T I O N + */ +struct v4l2_fmtdesc { + __u32 index; /* Format number */ + enum v4l2_buf_type type; /* buffer type */ + __u32 flags; + __u8 description[32]; /* Description string */ + __u32 pixelformat; /* Format fourcc */ + __u32 reserved[4]; +}; + +#define V4L2_FMT_FLAG_COMPRESSED 0x0001 +#define V4L2_FMT_FLAG_EMULATED 0x0002 + +#if 1 + /* Experimental Frame Size and frame rate enumeration */ +/* + * F R A M E S I Z E E N U M E R A T I O N + */ +enum v4l2_frmsizetypes { + V4L2_FRMSIZE_TYPE_DISCRETE = 1, + V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, + V4L2_FRMSIZE_TYPE_STEPWISE = 3, +}; + +struct v4l2_frmsize_discrete { + __u32 width; /* Frame width [pixel] */ + __u32 height; /* Frame height [pixel] */ +}; + +struct v4l2_frmsize_stepwise { + __u32 min_width; /* Minimum frame width [pixel] */ + __u32 max_width; /* Maximum frame width [pixel] */ + __u32 step_width; /* Frame width step size [pixel] */ + __u32 min_height; /* Minimum frame height [pixel] */ + __u32 max_height; /* Maximum frame height [pixel] */ + __u32 step_height; /* Frame height step size [pixel] */ +}; + +struct v4l2_frmsizeenum { + __u32 index; /* Frame size number */ + __u32 pixel_format; /* Pixel format */ + __u32 type; /* Frame size type the device supports. */ + + union { /* Frame size */ + struct v4l2_frmsize_discrete discrete; + struct v4l2_frmsize_stepwise stepwise; + }; + + __u32 reserved[2]; /* Reserved space for future use */ +}; + +/* + * F R A M E R A T E E N U M E R A T I O N + */ +enum v4l2_frmivaltypes { + V4L2_FRMIVAL_TYPE_DISCRETE = 1, + V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, + V4L2_FRMIVAL_TYPE_STEPWISE = 3, +}; + +struct v4l2_frmival_stepwise { + struct v4l2_fract min; /* Minimum frame interval [s] */ + struct v4l2_fract max; /* Maximum frame interval [s] */ + struct v4l2_fract step; /* Frame interval step size [s] */ +}; + +struct v4l2_frmivalenum { + __u32 index; /* Frame format index */ + __u32 pixel_format; /* Pixel format */ + __u32 width; /* Frame width */ + __u32 height; /* Frame height */ + __u32 type; /* Frame interval type the device supports. */ + + union { /* Frame interval */ + struct v4l2_fract discrete; + struct v4l2_frmival_stepwise stepwise; + }; + + __u32 reserved[2]; /* Reserved space for future use */ +}; +#endif + +/* + * T I M E C O D E + */ +struct v4l2_timecode { + __u32 type; + __u32 flags; + __u8 frames; + __u8 seconds; + __u8 minutes; + __u8 hours; + __u8 userbits[4]; +}; + +/* Type */ +#define V4L2_TC_TYPE_24FPS 1 +#define V4L2_TC_TYPE_25FPS 2 +#define V4L2_TC_TYPE_30FPS 3 +#define V4L2_TC_TYPE_50FPS 4 +#define V4L2_TC_TYPE_60FPS 5 + +/* Flags */ +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ +#define V4L2_TC_FLAG_COLORFRAME 0x0002 +#define V4L2_TC_USERBITS_field 0x000C +#define V4L2_TC_USERBITS_USERDEFINED 0x0000 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008 +/* The above is based on SMPTE timecodes */ + +struct v4l2_jpegcompression { + int quality; + + int APPn; /* Number of APP segment to be written, + * must be 0..15 */ + int APP_len; /* Length of data in JPEG APPn segment */ + char APP_data[60]; /* Data in the JPEG APPn segment. */ + + int COM_len; /* Length of data in JPEG COM segment */ + char COM_data[60]; /* Data in JPEG COM segment */ + + __u32 jpeg_markers; /* Which markers should go into the JPEG + * output. Unless you exactly know what + * you do, leave them untouched. + * Inluding less markers will make the + * resulting code smaller, but there will + * be fewer applications which can read it. + * The presence of the APP and COM marker + * is influenced by APP_len and COM_len + * ONLY, not by this property! */ + +#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ +#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ +#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ +#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ +#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will + * allways use APP0 */ +}; + +/* + * M E M O R Y - M A P P I N G B U F F E R S + */ +struct v4l2_requestbuffers { + __u32 count; + enum v4l2_buf_type type; + enum v4l2_memory memory; + __u32 reserved[2]; +}; + +/** + * struct v4l2_plane - plane info for multi-planar buffers + * @bytesused: number of bytes occupied by data in the plane (payload) + * @length: size of this plane (NOT the payload) in bytes + * @mem_offset: when memory in the associated struct v4l2_buffer is + * V4L2_MEMORY_MMAP, equals the offset from the start of + * the device memory for this plane (or is a "cookie" that + * should be passed to mmap() called on the video node) + * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer + * pointing to this plane + * @fd: when memory is V4L2_MEMORY_DMABUF, a userspace file + * descriptor associated with this plane + * @data_offset: offset in the plane to the start of data; usually 0, + * unless there is a header in front of the data + * + * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer + * with two planes can have one plane for Y, and another for interleaved CbCr + * components. Each plane can reside in a separate memory buffer, or even in + * a completely separate memory node (e.g. in embedded devices). + */ +struct v4l2_plane { + __u32 bytesused; + __u32 length; + union { + __u32 mem_offset; + unsigned long userptr; + int fd; + } m; + __u32 data_offset; + __u32 reserved[11]; +}; + +/** + * struct v4l2_buffer - video buffer info + * @index: id number of the buffer + * @type: buffer type (type == *_MPLANE for multiplanar buffers) + * @bytesused: number of bytes occupied by data in the buffer (payload); + * unused (set to 0) for multiplanar buffers + * @flags: buffer informational flags + * @field: field order of the image in the buffer + * @timestamp: frame timestamp + * @timecode: frame timecode + * @sequence: sequence count of this frame + * @memory: the method, in which the actual video data is passed + * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP; + * offset from the start of the device memory for this plane, + * (or a "cookie" that should be passed to mmap() as offset) + * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR; + * a userspace pointer pointing to this buffer + * @fd: for non-multiplanar buffers with + * memory == V4L2_MEMORY_DMABUF; a userspace file descriptor + * associated with this buffer + * @planes: for multiplanar buffers; userspace pointer to the array of plane + * info structs for this buffer + * @length: size in bytes of the buffer (NOT its payload) for single-plane + * buffers (when type != *_MPLANE); number of elements in the + * planes array for multi-plane buffers + * @input: input number from which the video data has has been captured + * + * Contains data exchanged by application and driver using one of the Streaming + * I/O methods. + */ +struct v4l2_buffer { + __u32 index; + enum v4l2_buf_type type; + __u32 bytesused; + __u32 flags; + enum v4l2_field field; + struct timeval timestamp; + struct v4l2_timecode timecode; + __u32 sequence; + + /* memory location */ + enum v4l2_memory memory; + union { + __u32 offset; + unsigned long userptr; + struct v4l2_plane *planes; + int fd; + } m; + __u32 length; + __u32 input; + __u32 reserved; +}; + +/* Flags for 'flags' field */ +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ +/* Buffer is ready, but the data contained within is corrupted. */ +#define V4L2_BUF_FLAG_ERROR 0x0040 +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ +#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ +#define V4L2_BUF_FLAG_PREPARED 0x0400 /* Buffer is prepared for queuing */ +/* Cache handling flags */ +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800 +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000 + +/* + * O V E R L A Y P R E V I E W + */ +struct v4l2_framebuffer { + __u32 capability; + __u32 flags; +/* FIXME: in theory we should pass something like PCI device + memory + * region + offset instead of some physical address */ + void *base; + struct v4l2_pix_format fmt; +}; +/* Flags for the 'capability' field. Read only */ +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 +#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 +#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010 +#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020 +#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040 +#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080 +/* Flags for the 'flags' field. */ +#define V4L2_FBUF_FLAG_PRIMARY 0x0001 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 +#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008 +#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010 +#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020 +#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040 + +struct v4l2_clip { + struct v4l2_rect c; + struct v4l2_clip __user *next; +}; + +struct v4l2_window { + struct v4l2_rect w; + enum v4l2_field field; + __u32 chromakey; + struct v4l2_clip __user *clips; + __u32 clipcount; + void __user *bitmap; + __u8 global_alpha; +}; + +/* + * C A P T U R E P A R A M E T E R S + */ +struct v4l2_captureparm { + __u32 capability; /* Supported modes */ + __u32 capturemode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in .1us units */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 readbuffers; /* # of buffers for read */ + __u32 reserved[4]; +}; + +/* Flags for 'capability' and 'capturemode' fields */ +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ + +struct v4l2_outputparm { + __u32 capability; /* Supported modes */ + __u32 outputmode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in seconds */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 writebuffers; /* # of buffers for write */ + __u32 reserved[4]; +}; + +/* + * I N P U T I M A G E C R O P P I N G + */ +struct v4l2_cropcap { + enum v4l2_buf_type type; + struct v4l2_rect bounds; + struct v4l2_rect defrect; + struct v4l2_fract pixelaspect; +}; + +struct v4l2_crop { + enum v4l2_buf_type type; + struct v4l2_rect c; +}; + +/* Hints for adjustments of selection rectangle */ +#define V4L2_SEL_FLAG_GE 0x00000001 +#define V4L2_SEL_FLAG_LE 0x00000002 + +/* Selection targets */ + +/* current cropping area */ +#define V4L2_SEL_TGT_CROP_ACTIVE 0 +/* default cropping area */ +#define V4L2_SEL_TGT_CROP_DEFAULT 1 +/* cropping bounds */ +#define V4L2_SEL_TGT_CROP_BOUNDS 2 +/* current composing area */ +#define V4L2_SEL_TGT_COMPOSE_ACTIVE 256 +/* default composing area */ +#define V4L2_SEL_TGT_COMPOSE_DEFAULT 257 +/* composing bounds */ +#define V4L2_SEL_TGT_COMPOSE_BOUNDS 258 +/* current composing area plus all padding pixels */ +#define V4L2_SEL_TGT_COMPOSE_PADDED 259 + +/** + * struct v4l2_selection - selection info + * @type: buffer type (do not use *_MPLANE types) + * @target: selection target, used to choose one of possible rectangles + * @flags: constraints flags + * @r: coordinates of selection window + * @reserved: for future use, rounds structure size to 64 bytes, set to zero + * + * Hardware may use multiple helper window to process a video stream. + * The structure is used to exchange this selection areas between + * an application and a driver. + */ +struct v4l2_selection { + __u32 type; + __u32 target; + __u32 flags; + struct v4l2_rect r; + __u32 reserved[9]; +}; + + +/* + * A N A L O G V I D E O S T A N D A R D + */ + +typedef __u64 v4l2_std_id; + +/* one bit for each */ +#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) +#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) +#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) +#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) +#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) +#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) +#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) +#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) + +#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) +#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) +#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) +#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) + +#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) /* BTSC */ +#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) /* EIA-J */ +#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) +#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) /* FM A2 */ + +#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) +#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) +#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) +#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) +#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) +#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) +#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) +#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000) + +/* ATSC/HDTV */ +#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) +#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) + +/* FIXME: + Although std_id is 64 bits, there is an issue on PPC32 architecture that + makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding + this value to 32 bits. + As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide), + it should work fine. However, if needed to add more than two standards, + v4l2-common.c should be fixed. + */ + +/* + * Some macros to merge video standards in order to make live easier for the + * drivers and V4L2 applications + */ + +/* + * "Common" NTSC/M - It should be noticed that V4L2_STD_NTSC_443 is + * Missing here. + */ +#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ + V4L2_STD_NTSC_M_JP |\ + V4L2_STD_NTSC_M_KR) +/* Secam macros */ +#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ + V4L2_STD_SECAM_K |\ + V4L2_STD_SECAM_K1) +/* All Secam Standards */ +#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ + V4L2_STD_SECAM_G |\ + V4L2_STD_SECAM_H |\ + V4L2_STD_SECAM_DK |\ + V4L2_STD_SECAM_L |\ + V4L2_STD_SECAM_LC) +/* PAL macros */ +#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_PAL_G) +#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ + V4L2_STD_PAL_D1 |\ + V4L2_STD_PAL_K) +/* + * "Common" PAL - This macro is there to be compatible with the old + * V4L1 concept of "PAL": /BGDKHI. + * Several PAL standards are mising here: /M, /N and /Nc + */ +#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ + V4L2_STD_PAL_DK |\ + V4L2_STD_PAL_H |\ + V4L2_STD_PAL_I) +/* Chroma "agnostic" standards */ +#define V4L2_STD_B (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_SECAM_B) +#define V4L2_STD_G (V4L2_STD_PAL_G |\ + V4L2_STD_SECAM_G) +#define V4L2_STD_H (V4L2_STD_PAL_H |\ + V4L2_STD_SECAM_H) +#define V4L2_STD_L (V4L2_STD_SECAM_L |\ + V4L2_STD_SECAM_LC) +#define V4L2_STD_GH (V4L2_STD_G |\ + V4L2_STD_H) +#define V4L2_STD_DK (V4L2_STD_PAL_DK |\ + V4L2_STD_SECAM_DK) +#define V4L2_STD_BG (V4L2_STD_B |\ + V4L2_STD_G) +#define V4L2_STD_MN (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_NTSC) + +/* Standards where MTS/BTSC stereo could be found */ +#define V4L2_STD_MTS (V4L2_STD_NTSC_M |\ + V4L2_STD_PAL_M |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc) + +/* Standards for Countries with 60Hz Line frequency */ +#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_60 |\ + V4L2_STD_NTSC |\ + V4L2_STD_NTSC_443) +/* Standards for Countries with 50Hz Line frequency */ +#define V4L2_STD_625_50 (V4L2_STD_PAL |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_SECAM) + +#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ + V4L2_STD_ATSC_16_VSB) +/* Macros with none and all analog standards */ +#define V4L2_STD_UNKNOWN 0 +#define V4L2_STD_ALL (V4L2_STD_525_60 |\ + V4L2_STD_625_50) + +struct v4l2_standard { + __u32 index; + v4l2_std_id id; + __u8 name[24]; + struct v4l2_fract frameperiod; /* Frames, not fields */ + __u32 framelines; + __u32 reserved[4]; +}; + +/* + * V I D E O T I M I N G S D V P R E S E T + */ +struct v4l2_dv_preset { + __u32 preset; + __u32 reserved[4]; +}; + +/* + * D V P R E S E T S E N U M E R A T I O N + */ +struct v4l2_dv_enum_preset { + __u32 index; + __u32 preset; + __u8 name[32]; /* Name of the preset timing */ + __u32 width; + __u32 height; + __u32 reserved[4]; +}; + +/* + * D V P R E S E T V A L U E S + */ +#define V4L2_DV_INVALID 0 +#define V4L2_DV_480P59_94 1 /* BT.1362 */ +#define V4L2_DV_576P50 2 /* BT.1362 */ +#define V4L2_DV_720P24 3 /* SMPTE 296M */ +#define V4L2_DV_720P25 4 /* SMPTE 296M */ +#define V4L2_DV_720P30 5 /* SMPTE 296M */ +#define V4L2_DV_720P50 6 /* SMPTE 296M */ +#define V4L2_DV_720P59_94 7 /* SMPTE 274M */ +#define V4L2_DV_720P60 8 /* SMPTE 274M/296M */ +#define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */ +#define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */ +#define V4L2_DV_1080I25 11 /* BT.1120 */ +#define V4L2_DV_1080I50 12 /* SMPTE 296M */ +#define V4L2_DV_1080I60 13 /* SMPTE 296M */ +#define V4L2_DV_1080P24 14 /* SMPTE 296M */ +#define V4L2_DV_1080P25 15 /* SMPTE 296M */ +#define V4L2_DV_1080P30 16 /* SMPTE 296M */ +#define V4L2_DV_1080P50 17 /* BT.1120 */ +#define V4L2_DV_1080P60 18 /* BT.1120 */ + +#define V4L2_DV_480P60 19 +#define V4L2_DV_1080I59_94 20 +#define V4L2_DV_1080P59_94 21 + +#define V4L2_DV_720P60_FP 22 +#define V4L2_DV_720P60_SB_HALF 23 +#define V4L2_DV_720P60_TB 24 +#define V4L2_DV_720P59_94_FP 25 +#define V4L2_DV_720P59_94_SB_HALF 26 +#define V4L2_DV_720P59_94_TB 27 +#define V4L2_DV_720P50_FP 28 +#define V4L2_DV_720P50_SB_HALF 29 +#define V4L2_DV_720P50_TB 30 +#define V4L2_DV_1080P24_FP 31 +#define V4L2_DV_1080P24_SB_HALF 32 +#define V4L2_DV_1080P24_TB 33 +#define V4L2_DV_1080P23_98_FP 34 +#define V4L2_DV_1080P23_98_SB_HALF 35 +#define V4L2_DV_1080P23_98_TB 36 +#define V4L2_DV_1080I60_SB_HALF 37 +#define V4L2_DV_1080I59_94_SB_HALF 38 +#define V4L2_DV_1080I50_SB_HALF 39 +#define V4L2_DV_1080P60_SB_HALF 40 +#define V4L2_DV_1080P60_TB 41 +#define V4L2_DV_1080P30_FP 42 +#define V4L2_DV_1080P30_SB_HALF 43 +#define V4L2_DV_1080P30_TB 44 + +/* + * D V B T T I M I N G S + */ + +/* BT.656/BT.1120 timing data */ +struct v4l2_bt_timings { + __u32 width; /* width in pixels */ + __u32 height; /* height in lines */ + __u32 interlaced; /* Interlaced or progressive */ + __u32 polarities; /* Positive or negative polarity */ + __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */ + __u32 hfrontporch; /* Horizpontal front porch in pixels */ + __u32 hsync; /* Horizontal Sync length in pixels */ + __u32 hbackporch; /* Horizontal back porch in pixels */ + __u32 vfrontporch; /* Vertical front porch in pixels */ + __u32 vsync; /* Vertical Sync length in lines */ + __u32 vbackporch; /* Vertical back porch in lines */ + __u32 il_vfrontporch; /* Vertical front porch for bottom field of + * interlaced field formats + */ + __u32 il_vsync; /* Vertical sync length for bottom field of + * interlaced field formats + */ + __u32 il_vbackporch; /* Vertical back porch for bottom field of + * interlaced field formats + */ + __u32 reserved[16]; +} __attribute__ ((packed)); + +/* Interlaced or progressive format */ +#define V4L2_DV_PROGRESSIVE 0 +#define V4L2_DV_INTERLACED 1 + +/* Polarities. If bit is not set, it is assumed to be negative polarity */ +#define V4L2_DV_VSYNC_POS_POL 0x00000001 +#define V4L2_DV_HSYNC_POS_POL 0x00000002 + + +/* DV timings */ +struct v4l2_dv_timings { + __u32 type; + union { + struct v4l2_bt_timings bt; + __u32 reserved[32]; + }; +} __attribute__ ((packed)); + +/* Values for the type field */ +#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ + +/* + * V I D E O I N P U T S + */ +struct v4l2_input { + __u32 index; /* Which input */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of input */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 tuner; /* Associated tuner */ + v4l2_std_id std; + __u32 status; + __u32 capabilities; + __u32 reserved[3]; +}; + +/* Values for the 'type' field */ +#define V4L2_INPUT_TYPE_TUNER 1 +#define V4L2_INPUT_TYPE_CAMERA 2 + +/* field 'status' - general */ +#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ +#define V4L2_IN_ST_NO_SIGNAL 0x00000002 +#define V4L2_IN_ST_NO_COLOR 0x00000004 + +/* field 'status' - sensor orientation */ +/* If sensor is mounted upside down set both bits */ +#define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */ +#define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */ + +/* field 'status' - analog */ +#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ +#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ + +/* field 'status' - digital */ +#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ +#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ +#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ + +/* field 'status' - VCR and set-top box */ +#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ +#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ +#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ + +/* capabilities flags */ +#define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ +#define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ +#define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ + +/* + * V I D E O O U T P U T S + */ +struct v4l2_output { + __u32 index; /* Which output */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of output */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 modulator; /* Associated modulator */ + v4l2_std_id std; + __u32 capabilities; + __u32 reserved[3]; +}; +/* Values for the 'type' field */ +#define V4L2_OUTPUT_TYPE_MODULATOR 1 +#define V4L2_OUTPUT_TYPE_ANALOG 2 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 + +/* capabilities flags */ +#define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ +#define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ +#define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ + +/* + * C O N T R O L S + */ +struct v4l2_control { + __u32 id; + __s32 value; +}; + +struct v4l2_ext_control { + __u32 id; + __u32 size; + __u32 reserved2[1]; + union { + __s32 value; + __s64 value64; + char *string; + }; +} __attribute__ ((packed)); + +struct v4l2_ext_controls { + __u32 ctrl_class; + __u32 count; + __u32 error_idx; + __u32 reserved[2]; + struct v4l2_ext_control *controls; +}; + +/* Values for ctrl_class field */ +#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ +#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ +#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ +#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */ +#define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */ +#define V4L2_CTRL_CLASS_FM_RX 0x009d0000 /* FM Tuner control class */ + +#define V4L2_CTRL_ID_MASK (0x0fffffff) +#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) +#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) + +enum v4l2_ctrl_type { + V4L2_CTRL_TYPE_INTEGER = 1, + V4L2_CTRL_TYPE_BOOLEAN = 2, + V4L2_CTRL_TYPE_MENU = 3, + V4L2_CTRL_TYPE_BUTTON = 4, + V4L2_CTRL_TYPE_INTEGER64 = 5, + V4L2_CTRL_TYPE_CTRL_CLASS = 6, + V4L2_CTRL_TYPE_STRING = 7, + V4L2_CTRL_TYPE_BITMASK = 8, +}; + +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ +struct v4l2_queryctrl { + __u32 id; + enum v4l2_ctrl_type type; + __u8 name[32]; /* Whatever */ + __s32 minimum; /* Note signedness */ + __s32 maximum; + __s32 step; + __s32 default_value; + __u32 flags; + __u32 reserved[2]; +}; + +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ +struct v4l2_querymenu { + __u32 id; + __u32 index; + __u8 name[32]; /* Whatever */ + __u32 reserved; +}; + +/* Control flags */ +#define V4L2_CTRL_FLAG_DISABLED 0x0001 +#define V4L2_CTRL_FLAG_GRABBED 0x0002 +#define V4L2_CTRL_FLAG_READ_ONLY 0x0004 +#define V4L2_CTRL_FLAG_UPDATE 0x0008 +#define V4L2_CTRL_FLAG_INACTIVE 0x0010 +#define V4L2_CTRL_FLAG_SLIDER 0x0020 +#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 +#define V4L2_CTRL_FLAG_VOLATILE 0x0080 + +/* Query flag, to be ORed with the control ID */ +#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 + +/* User-class control IDs defined by V4L2 */ +#define V4L2_CID_MAX_CTRLS 1024 +#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) +#define V4L2_CID_USER_BASE V4L2_CID_BASE +/* IDs reserved for driver specific controls */ +#define V4L2_CID_PRIVATE_BASE 0x08000000 + +#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) +#define V4L2_CID_HUE (V4L2_CID_BASE+3) +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */ +#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */ +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) +#define V4L2_CID_GAIN (V4L2_CID_BASE+19) +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) + +/* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */ +#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) +#define V4L2_CID_VCENTER (V4L2_CID_BASE+23) + +#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) +enum v4l2_power_line_frequency { + V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, + V4L2_CID_POWER_LINE_FREQUENCY_AUTO = 3, +}; +#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) +#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) +#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) +#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) +#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) +#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) +#define V4L2_CID_COLORFX (V4L2_CID_BASE+31) +enum v4l2_colorfx { + V4L2_COLORFX_NONE = 0, + V4L2_COLORFX_BW = 1, + V4L2_COLORFX_SEPIA = 2, + V4L2_COLORFX_NEGATIVE = 3, + V4L2_COLORFX_EMBOSS = 4, + V4L2_COLORFX_SKETCH = 5, + V4L2_COLORFX_SKY_BLUE = 6, + V4L2_COLORFX_GRASS_GREEN = 7, + V4L2_COLORFX_SKIN_WHITEN = 8, + V4L2_COLORFX_VIVID = 9, +}; +#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) +#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) + +#define V4L2_CID_ROTATE (V4L2_CID_BASE+34) +#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) + +#define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) + +#define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37) +#define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38) + +#define V4L2_CID_MIN_BUFFERS_FOR_CAPTURE (V4L2_CID_BASE+39) +#define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40) + +#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41) + +/* last CID + 1 */ +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+42) + +/* MPEG-class control IDs defined by V4L2 */ +#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) +#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) + +/* MPEG streams, specific to multiplexed streams */ +#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) +enum v4l2_mpeg_stream_type { + V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */ + V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */ + V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */ +}; +#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) +#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) +#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) +#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) +#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) +#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) +#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) +enum v4l2_mpeg_stream_vbi_fmt { + V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */ + V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */ +}; + +/* MPEG audio controls specific to multiplexed streams */ +#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) +enum v4l2_mpeg_audio_sampling_freq { + V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2, +}; +#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) +enum v4l2_mpeg_audio_encoding { + V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, + V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, + V4L2_MPEG_AUDIO_ENCODING_AAC = 3, + V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, +}; +#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) +enum v4l2_mpeg_audio_l1_bitrate { + V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1, + V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2, + V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3, + V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4, + V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5, + V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6, + V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7, + V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8, + V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9, + V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10, + V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11, + V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12, + V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) +enum v4l2_mpeg_audio_l2_bitrate { + V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1, + V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2, + V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3, + V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4, + V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5, + V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6, + V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7, + V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8, + V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9, + V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10, + V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11, + V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12, + V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) +enum v4l2_mpeg_audio_l3_bitrate { + V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) +enum v4l2_mpeg_audio_mode { + V4L2_MPEG_AUDIO_MODE_STEREO = 0, + V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1, + V4L2_MPEG_AUDIO_MODE_DUAL = 2, + V4L2_MPEG_AUDIO_MODE_MONO = 3, +}; +#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) +enum v4l2_mpeg_audio_mode_extension { + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3, +}; +#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) +enum v4l2_mpeg_audio_emphasis { + V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0, + V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1, + V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2, +}; +#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) +enum v4l2_mpeg_audio_crc { + V4L2_MPEG_AUDIO_CRC_NONE = 0, + V4L2_MPEG_AUDIO_CRC_CRC16 = 1, +}; +#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) +#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) +#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) +enum v4l2_mpeg_audio_ac3_bitrate { + V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13, + V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14, + V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15, + V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16, + V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, + V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, +}; + +/* MPEG video controls specific to multiplexed streams */ +#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) +enum v4l2_mpeg_video_encoding { + V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, +}; +#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) +enum v4l2_mpeg_video_aspect { + V4L2_MPEG_VIDEO_ASPECT_1x1 = 0, + V4L2_MPEG_VIDEO_ASPECT_4x3 = 1, + V4L2_MPEG_VIDEO_ASPECT_16x9 = 2, + V4L2_MPEG_VIDEO_ASPECT_221x100 = 3, +}; +#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) +#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) +#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) +#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) +#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) +enum v4l2_mpeg_video_bitrate_mode { + V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, +}; +#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) +#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) +#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) +#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) +#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) +#define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE+212) +#define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE+213) +#define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE+214) +#define V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (V4L2_CID_MPEG_BASE+215) +#define V4L2_CID_MPEG_VIDEO_HEADER_MODE (V4L2_CID_MPEG_BASE+216) +enum v4l2_mpeg_video_header_mode { + V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0, + V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1, + +}; +#define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE+217) +#define V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (V4L2_CID_MPEG_BASE+218) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (V4L2_CID_MPEG_BASE+219) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (V4L2_CID_MPEG_BASE+220) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE+221) +enum v4l2_mpeg_video_multi_slice_mode { + V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0, + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1, + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2, +}; +#define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222) +#define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) +#define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) +#define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) +#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP (V4L2_CID_MPEG_BASE+303) +#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP (V4L2_CID_MPEG_BASE+304) +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (V4L2_CID_MPEG_BASE+350) +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (V4L2_CID_MPEG_BASE+351) +#define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (V4L2_CID_MPEG_BASE+352) +#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP (V4L2_CID_MPEG_BASE+353) +#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP (V4L2_CID_MPEG_BASE+354) +#define V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (V4L2_CID_MPEG_BASE+355) +#define V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (V4L2_CID_MPEG_BASE+356) +#define V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE (V4L2_CID_MPEG_BASE+357) +enum v4l2_mpeg_video_h264_entropy_mode { + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC = 0, + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (V4L2_CID_MPEG_BASE+358) +#define V4L2_CID_MPEG_VIDEO_H264_LEVEL (V4L2_CID_MPEG_BASE+359) +enum v4l2_mpeg_video_h264_level { + V4L2_MPEG_VIDEO_H264_LEVEL_1_0 = 0, + V4L2_MPEG_VIDEO_H264_LEVEL_1B = 1, + V4L2_MPEG_VIDEO_H264_LEVEL_1_1 = 2, + V4L2_MPEG_VIDEO_H264_LEVEL_1_2 = 3, + V4L2_MPEG_VIDEO_H264_LEVEL_1_3 = 4, + V4L2_MPEG_VIDEO_H264_LEVEL_2_0 = 5, + V4L2_MPEG_VIDEO_H264_LEVEL_2_1 = 6, + V4L2_MPEG_VIDEO_H264_LEVEL_2_2 = 7, + V4L2_MPEG_VIDEO_H264_LEVEL_3_0 = 8, + V4L2_MPEG_VIDEO_H264_LEVEL_3_1 = 9, + V4L2_MPEG_VIDEO_H264_LEVEL_3_2 = 10, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0 = 11, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1 = 12, + V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15, +}; +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE+360) +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE+361) +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE+362) +enum v4l2_mpeg_video_h264_loop_filter_mode { + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED = 0, + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED = 1, + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2, +}; +#define V4L2_CID_MPEG_VIDEO_H264_PROFILE (V4L2_CID_MPEG_BASE+363) +enum v4l2_mpeg_video_h264_profile { + V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE = 0, + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE = 1, + V4L2_MPEG_VIDEO_H264_PROFILE_MAIN = 2, + V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED = 3, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH = 4, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 = 5, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422 = 6, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE = 7, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA = 8, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA = 9, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA = 10, + V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA = 11, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14, + V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15, + V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16, +}; +#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+364) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+365) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (V4L2_CID_MPEG_BASE+366) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC (V4L2_CID_MPEG_BASE+367) +enum v4l2_mpeg_video_h264_vui_sar_idc { + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED = 0, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 = 1, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 = 2, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 = 3, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 = 4, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 = 5, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 = 6, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 = 7, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 = 8, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 = 9, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 = 10, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 = 11, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 = 12, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 = 13, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 = 14, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 = 15, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 = 16, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED = 17, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400) +#define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401) +#define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402) +#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (V4L2_CID_MPEG_BASE+403) +#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (V4L2_CID_MPEG_BASE+404) +#define V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL (V4L2_CID_MPEG_BASE+405) +enum v4l2_mpeg_video_mpeg4_level { + V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 = 0, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B = 1, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 = 2, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 = 3, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 = 4, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B = 5, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 = 6, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 = 7, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE (V4L2_CID_MPEG_BASE+406) +enum v4l2_mpeg_video_mpeg4_profile { + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE = 0, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE = 1, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE = 2, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE = 3, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY = 4, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (V4L2_CID_MPEG_BASE+407) + +/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ +#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) +enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0, + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) +enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) +enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type { + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) +enum v4l2_mpeg_cx2341x_video_temporal_filter_mode { + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0, + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) +#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) +enum v4l2_mpeg_cx2341x_video_median_filter_type { + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) +#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) + +/* MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */ +#define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100) + +#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (V4L2_CID_MPEG_MFC51_BASE+0) +#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (V4L2_CID_MPEG_MFC51_BASE+1) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_MFC51_BASE+2) +enum v4l2_mpeg_mfc51_video_frame_skip_mode { + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED = 0, + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1, + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2, +}; +#define V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE (V4L2_CID_MPEG_MFC51_BASE+3) +enum v4l2_mpeg_mfc51_video_force_frame_type { + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED = 0, + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME = 1, + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED = 2, +}; +#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING (V4L2_CID_MPEG_MFC51_BASE+4) +#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (V4L2_CID_MPEG_MFC51_BASE+5) +#define V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (V4L2_CID_MPEG_MFC51_BASE+6) +#define V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (V4L2_CID_MPEG_MFC51_BASE+7) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC51_BASE+50) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC51_BASE+51) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC51_BASE+52) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54) + +/* Camera class control IDs */ +#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) +#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) + +#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) +enum v4l2_exposure_auto_type { + V4L2_EXPOSURE_AUTO = 0, + V4L2_EXPOSURE_MANUAL = 1, + V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, + V4L2_EXPOSURE_APERTURE_PRIORITY = 3 +}; +#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) +#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) + +#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) +#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) +#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) +#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) + +#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) +#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) + +#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) +#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) +#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) + +#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) +#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) +#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) + +#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) + +#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17) +#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18) + +/* FM Modulator class control IDs */ +#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) +#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) + +#define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1) +#define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2) +#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3) +#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5) +#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6) + +#define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64) +#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65) +#define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66) + +#define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80) +#define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81) +#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82) +#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83) +#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84) + +#define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96) +#define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97) +#define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98) + +#define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112) +enum v4l2_preemphasis { + V4L2_PREEMPHASIS_DISABLED = 0, + V4L2_PREEMPHASIS_50_uS = 1, + V4L2_PREEMPHASIS_75_uS = 2, +}; +#define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113) +#define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114) +/* FM Tuner class control IDs */ +#define V4L2_CID_FM_RX_CLASS_BASE (V4L2_CTRL_CLASS_FM_RX | 0x900) +#define V4L2_CID_FM_RX_CLASS (V4L2_CTRL_CLASS_FM_RX | 1) + +#define V4L2_CID_TUNE_DEEMPHASIS (V4L2_CID_FM_RX_CLASS_BASE + 1) +enum v4l2_deemphasis { + V4L2_DEEMPHASIS_DISABLED = 0, + V4L2_DEEMPHASIS_50_uS = 1, + V4L2_DEEMPHASIS_75_uS = 2, +}; + +/* Flash and privacy (indicator) light controls */ +#define V4L2_CID_FLASH_CLASS_BASE (V4L2_CTRL_CLASS_FLASH | 0x900) +#define V4L2_CID_FLASH_CLASS (V4L2_CTRL_CLASS_FLASH | 1) + +#define V4L2_CID_FLASH_LED_MODE (V4L2_CID_FLASH_CLASS_BASE + 1) +enum v4l2_flash_led_mode { + V4L2_FLASH_LED_MODE_NONE, + V4L2_FLASH_LED_MODE_FLASH, + V4L2_FLASH_LED_MODE_TORCH, +}; + +#define V4L2_CID_FLASH_STROBE_SOURCE (V4L2_CID_FLASH_CLASS_BASE + 2) +enum v4l2_flash_strobe_source { + V4L2_FLASH_STROBE_SOURCE_SOFTWARE, + V4L2_FLASH_STROBE_SOURCE_EXTERNAL, +}; + +#define V4L2_CID_FLASH_STROBE (V4L2_CID_FLASH_CLASS_BASE + 3) +#define V4L2_CID_FLASH_STROBE_STOP (V4L2_CID_FLASH_CLASS_BASE + 4) +#define V4L2_CID_FLASH_STROBE_STATUS (V4L2_CID_FLASH_CLASS_BASE + 5) + +#define V4L2_CID_FLASH_TIMEOUT (V4L2_CID_FLASH_CLASS_BASE + 6) +#define V4L2_CID_FLASH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 7) +#define V4L2_CID_FLASH_TORCH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 8) +#define V4L2_CID_FLASH_INDICATOR_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 9) + +#define V4L2_CID_FLASH_FAULT (V4L2_CID_FLASH_CLASS_BASE + 10) +#define V4L2_FLASH_FAULT_OVER_VOLTAGE (1 << 0) +#define V4L2_FLASH_FAULT_TIMEOUT (1 << 1) +#define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2) +#define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3) +#define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4) +#define V4L2_FLASH_FAULT_INDICATOR (1 << 5) + +#define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11) +#define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12) + +/* + * T U N I N G + */ +struct v4l2_tuner { + __u32 index; + __u8 name[32]; + enum v4l2_tuner_type type; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 rxsubchans; + __u32 audmode; + __s32 signal; + __s32 afc; + __u32 reserved[4]; +}; + +struct v4l2_modulator { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 txsubchans; + __u32 reserved[4]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_TUNER_CAP_LOW 0x0001 +#define V4L2_TUNER_CAP_NORM 0x0002 +#define V4L2_TUNER_CAP_STEREO 0x0010 +#define V4L2_TUNER_CAP_LANG2 0x0020 +#define V4L2_TUNER_CAP_SAP 0x0020 +#define V4L2_TUNER_CAP_LANG1 0x0040 +#define V4L2_TUNER_CAP_RDS 0x0080 +#define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100 +#define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200 + +/* Flags for the 'rxsubchans' field */ +#define V4L2_TUNER_SUB_MONO 0x0001 +#define V4L2_TUNER_SUB_STEREO 0x0002 +#define V4L2_TUNER_SUB_LANG2 0x0004 +#define V4L2_TUNER_SUB_SAP 0x0004 +#define V4L2_TUNER_SUB_LANG1 0x0008 +#define V4L2_TUNER_SUB_RDS 0x0010 + +/* Values for the 'audmode' field */ +#define V4L2_TUNER_MODE_MONO 0x0000 +#define V4L2_TUNER_MODE_STEREO 0x0001 +#define V4L2_TUNER_MODE_LANG2 0x0002 +#define V4L2_TUNER_MODE_SAP 0x0002 +#define V4L2_TUNER_MODE_LANG1 0x0003 +#define V4L2_TUNER_MODE_LANG1_LANG2 0x0004 + +struct v4l2_frequency { + __u32 tuner; + enum v4l2_tuner_type type; + __u32 frequency; + __u32 reserved[8]; +}; + +struct v4l2_hw_freq_seek { + __u32 tuner; + enum v4l2_tuner_type type; + __u32 seek_upward; + __u32 wrap_around; + __u32 spacing; + __u32 reserved[7]; +}; + +/* + * R D S + */ + +struct v4l2_rds_data { + __u8 lsb; + __u8 msb; + __u8 block; +} __attribute__ ((packed)); + +#define V4L2_RDS_BLOCK_MSK 0x7 +#define V4L2_RDS_BLOCK_A 0 +#define V4L2_RDS_BLOCK_B 1 +#define V4L2_RDS_BLOCK_C 2 +#define V4L2_RDS_BLOCK_D 3 +#define V4L2_RDS_BLOCK_C_ALT 4 +#define V4L2_RDS_BLOCK_INVALID 7 + +#define V4L2_RDS_BLOCK_CORRECTED 0x40 +#define V4L2_RDS_BLOCK_ERROR 0x80 + +/* + * A U D I O + */ +struct v4l2_audio { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_AUDCAP_STEREO 0x00001 +#define V4L2_AUDCAP_AVL 0x00002 + +/* Flags for the 'mode' field */ +#define V4L2_AUDMODE_AVL 0x00001 + +struct v4l2_audioout { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* + * M P E G S E R V I C E S + * + * NOTE: EXPERIMENTAL API + */ +#if 1 +#define V4L2_ENC_IDX_FRAME_I (0) +#define V4L2_ENC_IDX_FRAME_P (1) +#define V4L2_ENC_IDX_FRAME_B (2) +#define V4L2_ENC_IDX_FRAME_MASK (0xf) + +struct v4l2_enc_idx_entry { + __u64 offset; + __u64 pts; + __u32 length; + __u32 flags; + __u32 reserved[2]; +}; + +#define V4L2_ENC_IDX_ENTRIES (64) +struct v4l2_enc_idx { + __u32 entries; + __u32 entries_cap; + __u32 reserved[4]; + struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES]; +}; + + +#define V4L2_ENC_CMD_START (0) +#define V4L2_ENC_CMD_STOP (1) +#define V4L2_ENC_CMD_PAUSE (2) +#define V4L2_ENC_CMD_RESUME (3) + +/* Flags for V4L2_ENC_CMD_STOP */ +#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0) + +struct v4l2_encoder_cmd { + __u32 cmd; + __u32 flags; + union { + struct { + __u32 data[8]; + } raw; + }; +}; + +#endif + + +/* + * D A T A S E R V I C E S ( V B I ) + * + * Data services API by Michael Schimek + */ + +/* Raw VBI */ +struct v4l2_vbi_format { + __u32 sampling_rate; /* in 1 Hz */ + __u32 offset; + __u32 samples_per_line; + __u32 sample_format; /* V4L2_PIX_FMT_* */ + __s32 start[2]; + __u32 count[2]; + __u32 flags; /* V4L2_VBI_* */ + __u32 reserved[2]; /* must be zero */ +}; + +/* VBI flags */ +#define V4L2_VBI_UNSYNC (1 << 0) +#define V4L2_VBI_INTERLACED (1 << 1) + +/* Sliced VBI + * + * This implements is a proposal V4L2 API to allow SLICED VBI + * required for some hardware encoders. It should change without + * notice in the definitive implementation. + */ + +struct v4l2_sliced_vbi_format { + __u16 service_set; + /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field + service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field + (equals frame lines 313-336 for 625 line video + standards, 263-286 for 525 line standards) */ + __u16 service_lines[2][24]; + __u32 io_size; + __u32 reserved[2]; /* must be zero */ +}; + +/* Teletext World System Teletext + (WST), defined on ITU-R BT.653-2 */ +#define V4L2_SLICED_TELETEXT_B (0x0001) +/* Video Program System, defined on ETS 300 231*/ +#define V4L2_SLICED_VPS (0x0400) +/* Closed Caption, defined on EIA-608 */ +#define V4L2_SLICED_CAPTION_525 (0x1000) +/* Wide Screen System, defined on ITU-R BT1119.1 */ +#define V4L2_SLICED_WSS_625 (0x4000) + +#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) +#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) + +struct v4l2_sliced_vbi_cap { + __u16 service_set; + /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field + service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field + (equals frame lines 313-336 for 625 line video + standards, 263-286 for 525 line standards) */ + __u16 service_lines[2][24]; + enum v4l2_buf_type type; + __u32 reserved[3]; /* must be 0 */ +}; + +struct v4l2_sliced_vbi_data { + __u32 id; + __u32 field; /* 0: first field, 1: second field */ + __u32 line; /* 1-23 */ + __u32 reserved; /* must be 0 */ + __u8 data[48]; +}; + +/* + * Sliced VBI data inserted into MPEG Streams + */ + +/* + * V4L2_MPEG_STREAM_VBI_FMT_IVTV: + * + * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an + * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI + * data + * + * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header + * definitions are not included here. See the MPEG-2 specifications for details + * on these headers. + */ + +/* Line type IDs */ +#define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1) +#define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4) +#define V4L2_MPEG_VBI_IVTV_WSS_625 (5) +#define V4L2_MPEG_VBI_IVTV_VPS (7) + +struct v4l2_mpeg_vbi_itv0_line { + __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */ + __u8 data[42]; /* Sliced VBI data for the line */ +} __attribute__ ((packed)); + +struct v4l2_mpeg_vbi_itv0 { + __le32 linemask[2]; /* Bitmasks of VBI service lines present */ + struct v4l2_mpeg_vbi_itv0_line line[35]; +} __attribute__ ((packed)); + +struct v4l2_mpeg_vbi_ITV0 { + struct v4l2_mpeg_vbi_itv0_line line[36]; +} __attribute__ ((packed)); + +#define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0" +#define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0" + +struct v4l2_mpeg_vbi_fmt_ivtv { + __u8 magic[4]; + union { + struct v4l2_mpeg_vbi_itv0 itv0; + struct v4l2_mpeg_vbi_ITV0 ITV0; + }; +} __attribute__ ((packed)); + +/* + * A G G R E G A T E S T R U C T U R E S + */ + +/** + * struct v4l2_plane_pix_format - additional, per-plane format definition + * @sizeimage: maximum size in bytes required for data, for which + * this plane will be used + * @bytesperline: distance in bytes between the leftmost pixels in two + * adjacent lines + */ +struct v4l2_plane_pix_format { + __u32 sizeimage; + __u16 bytesperline; + __u16 reserved[7]; +} __attribute__ ((packed)); + +/** + * struct v4l2_pix_format_mplane - multiplanar format definition + * @width: image width in pixels + * @height: image height in pixels + * @pixelformat: little endian four character code (fourcc) + * @field: field order (for interlaced video) + * @colorspace: supplemental to pixelformat + * @plane_fmt: per-plane information + * @num_planes: number of planes for this format + */ +struct v4l2_pix_format_mplane { + __u32 width; + __u32 height; + __u32 pixelformat; + enum v4l2_field field; + enum v4l2_colorspace colorspace; + + struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES]; + __u8 num_planes; + __u8 reserved[11]; +} __attribute__ ((packed)); + +/** + * struct v4l2_format - stream data format + * @type: type of the data stream + * @pix: definition of an image format + * @pix_mp: definition of a multiplanar image format + * @win: definition of an overlaid image + * @vbi: raw VBI capture or output parameters + * @sliced: sliced VBI capture or output parameters + * @raw_data: placeholder for future extensions and custom formats + */ +struct v4l2_format { + enum v4l2_buf_type type; + union { + struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ + struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ + struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ + struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ + struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ + __u8 raw_data[200]; /* user-defined */ + } fmt; +}; + +/* Stream type-dependent parameters + */ +struct v4l2_streamparm { + enum v4l2_buf_type type; + union { + struct v4l2_captureparm capture; + struct v4l2_outputparm output; + __u8 raw_data[200]; /* user-defined */ + } parm; +}; + +/* + * E V E N T S + */ + +#define V4L2_EVENT_ALL 0 +#define V4L2_EVENT_VSYNC 1 +#define V4L2_EVENT_EOS 2 +#define V4L2_EVENT_CTRL 3 +#define V4L2_EVENT_FRAME_SYNC 4 +#define V4L2_EVENT_PRIVATE_START 0x08000000 + +/* Payload for V4L2_EVENT_VSYNC */ +struct v4l2_event_vsync { + /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */ + __u8 field; +} __attribute__ ((packed)); + +/* Payload for V4L2_EVENT_CTRL */ +#define V4L2_EVENT_CTRL_CH_VALUE (1 << 0) +#define V4L2_EVENT_CTRL_CH_FLAGS (1 << 1) + +struct v4l2_event_ctrl { + __u32 changes; + __u32 type; + union { + __s32 value; + __s64 value64; + }; + __u32 flags; + __s32 minimum; + __s32 maximum; + __s32 step; + __s32 default_value; +}; + +struct v4l2_event_frame_sync { + __u32 frame_sequence; +}; + +struct v4l2_event { + __u32 type; + union { + struct v4l2_event_vsync vsync; + struct v4l2_event_ctrl ctrl; + struct v4l2_event_frame_sync frame_sync; + __u8 data[64]; + } u; + __u32 pending; + __u32 sequence; + struct timespec timestamp; + __u32 id; + __u32 reserved[8]; +}; + +#define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0) +#define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK (1 << 1) + +struct v4l2_event_subscription { + __u32 type; + __u32 id; + __u32 flags; + __u32 reserved[5]; +}; + +/* + * A D V A N C E D D E B U G G I N G + * + * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! + * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY! + */ + +/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ + +#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ +#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */ +#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ +#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */ + +struct v4l2_dbg_match { + __u32 type; /* Match type */ + union { /* Match this chip, meaning determined by type */ + __u32 addr; + char name[32]; + }; +} __attribute__ ((packed)); + +struct v4l2_dbg_register { + struct v4l2_dbg_match match; + __u32 size; /* register size in bytes */ + __u64 reg; + __u64 val; +} __attribute__ ((packed)); + +/* VIDIOC_DBG_G_CHIP_IDENT */ +struct v4l2_dbg_chip_ident { + struct v4l2_dbg_match match; + __u32 ident; /* chip identifier as specified in */ + __u32 revision; /* chip revision, chip specific */ +} __attribute__ ((packed)); + +/** + * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument + * @index: on return, index of the first created buffer + * @count: entry: number of requested buffers, + * return: number of created buffers + * @memory: buffer memory type + * @format: frame format, for which buffers are requested + * @reserved: future extensions + */ +struct v4l2_create_buffers { + __u32 index; + __u32 count; + enum v4l2_memory memory; + struct v4l2_format format; + __u32 reserved[8]; +}; + +/* + * I O C T L C O D E S F O R V I D E O D E V I C E S + * + */ +#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability) +#define VIDIOC_RESERVED _IO('V', 1) +#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc) +#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) +#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format) +#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers) +#define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer) +#define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer) +#define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer) +#define VIDIOC_OVERLAY _IOW('V', 14, int) +#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer) +#define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer) +#define VIDIOC_STREAMON _IOW('V', 18, int) +#define VIDIOC_STREAMOFF _IOW('V', 19, int) +#define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm) +#define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm) +#define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id) +#define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id) +#define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard) +#define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input) +#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control) +#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control) +#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner) +#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner) +#define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio) +#define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio) +#define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl) +#define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu) +#define VIDIOC_G_INPUT _IOR('V', 38, int) +#define VIDIOC_S_INPUT _IOWR('V', 39, int) +#define VIDIOC_G_OUTPUT _IOR('V', 46, int) +#define VIDIOC_S_OUTPUT _IOWR('V', 47, int) +#define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output) +#define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout) +#define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout) +#define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator) +#define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator) +#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency) +#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency) +#define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap) +#define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop) +#define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop) +#define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression) +#define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression) +#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id) +#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format) +#define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio) +#define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout) +#define VIDIOC_G_PRIORITY _IOR('V', 67, enum v4l2_priority) +#define VIDIOC_S_PRIORITY _IOW('V', 68, enum v4l2_priority) +#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap) +#define VIDIOC_LOG_STATUS _IO('V', 70) +#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls) +#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls) +#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls) +#if 1 +#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum) +#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum) +#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx) +#define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) +#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) +#endif + +#if 1 +/* Experimental, meant for debugging, testing and internal use. + Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. + You must be root to use these ioctls. Never use these in applications! */ +#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) +#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) + +/* Experimental, meant for debugging, testing and internal use. + Never use this ioctl in applications! */ +#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident) +#endif + +#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) +#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset) +#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset) +#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset) +#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset) +#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) +#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) +#define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event) +#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription) +#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription) + +/* Experimental, the below two ioctls may change over the next couple of kernel + versions */ +#define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers) +#define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer) + +/* Experimental selection API */ +#define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection) +#define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection) + +/* Reminder: when adding new ioctls please add support for them to + drivers/media/video/v4l2-compat-ioctl32.c as well! */ + +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ + +#endif /* __LINUX_VIDEODEV2_H */ diff --git a/camera/include/linux/videodev2_exynos_camera.h b/camera/include/linux/videodev2_exynos_camera.h new file mode 100644 index 0000000..557b5e1 --- /dev/null +++ b/camera/include/linux/videodev2_exynos_camera.h @@ -0,0 +1,2047 @@ +/* + * Video for Linux Two header file for samsung + * + * Copyright (C) 2009, Dongsoo Nathaniel Kim + * + * This header file contains several v4l2 APIs to be proposed to v4l2 + * community and until bein accepted, will be used restrictly in Samsung's + * camera interface driver FIMC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __LINUX_VIDEODEV2_SAMSUNG_H +#define __LINUX_VIDEODEV2_SAMSUNG_H + +/* Values for 'capabilities' field */ +/* Object detection device */ +#define V4L2_CAP_OBJ_RECOGNITION 0x10000000 +/* strobe control */ +#define V4L2_CAP_STROBE 0x20000000 + +#define V4L2_CID_FOCUS_MODE (V4L2_CID_CAMERA_CLASS_BASE+17) +/* Focus Methods */ +enum v4l2_focus_mode { + V4L2_FOCUS_MODE_AUTO = 0, + V4L2_FOCUS_MODE_MACRO = 1, + V4L2_FOCUS_MODE_MANUAL = 2, + V4L2_FOCUS_MODE_LASTP = 2, +}; + +#define V4L2_CID_ZOOM_MODE (V4L2_CID_CAMERA_CLASS_BASE+18) +/* Zoom Methods */ +enum v4l2_zoom_mode { + V4L2_ZOOM_MODE_CONTINUOUS = 0, + V4L2_ZOOM_MODE_OPTICAL = 1, + V4L2_ZOOM_MODE_DIGITAL = 2, + V4L2_ZOOM_MODE_LASTP = 2, +}; + +/* Exposure Methods */ +#define V4L2_CID_PHOTOMETRY (V4L2_CID_CAMERA_CLASS_BASE+19) +enum v4l2_photometry_mode { + V4L2_PHOTOMETRY_MULTISEG = 0, /*Multi Segment*/ + V4L2_PHOTOMETRY_CWA = 1, /*Centre Weighted Average*/ + V4L2_PHOTOMETRY_SPOT = 2, + V4L2_PHOTOMETRY_AFSPOT = 3, /*Spot metering on focused point*/ + V4L2_PHOTOMETRY_LASTP = V4L2_PHOTOMETRY_AFSPOT, +}; + +/* Manual exposure control items menu type: iris, shutter, iso */ +#define V4L2_CID_CAM_APERTURE (V4L2_CID_CAMERA_CLASS_BASE+20) +enum v4l2_aperture_mode { + APERTURE_F_AUTO = 0, + APERTURE_F_2_8, + APERTURE_F_3_2, + APERTURE_F_3_6, + APERTURE_F_4_0, + APERTURE_F_4_5, + APERTURE_F_5_1, + APERTURE_F_5_7, + APERTURE_F_6_4, + APERTURE_F_7_2, + APERTURE_MAX, +}; +#define V4L2_CID_CAM_SHUTTER (V4L2_CID_CAMERA_CLASS_BASE+21) +#define V4L2_CID_CAM_ISO (V4L2_CID_CAMERA_CLASS_BASE+22) + +/* Following CIDs are menu type */ +#define V4L2_CID_SCENEMODE (V4L2_CID_CAMERA_CLASS_BASE+23) +#define V4L2_CID_CAM_STABILIZE (V4L2_CID_CAMERA_CLASS_BASE+24) +#define V4L2_CID_CAM_MULTISHOT (V4L2_CID_CAMERA_CLASS_BASE+25) + +/* Control dynamic range */ +#define V4L2_CID_CAM_DR (V4L2_CID_CAMERA_CLASS_BASE+26) + +/* White balance preset control */ +#define V4L2_CID_WHITE_BALANCE_PRESET (V4L2_CID_CAMERA_CLASS_BASE+27) +#define V4L2_CID_CAM_SENSOR_FW_VER (V4L2_CID_CAMERA_CLASS_BASE + 28) +#define V4L2_CID_CAM_PHONE_FW_VER (V4L2_CID_CAMERA_CLASS_BASE + 29) + +/* CID extensions */ +#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_PADDR_Y (V4L2_CID_PRIVATE_BASE + 1) +#define V4L2_CID_PADDR_CB (V4L2_CID_PRIVATE_BASE + 2) +#define V4L2_CID_PADDR_CR (V4L2_CID_PRIVATE_BASE + 3) +#define V4L2_CID_PADDR_CBCR (V4L2_CID_PRIVATE_BASE + 4) +#define V4L2_CID_OVERLAY_AUTO (V4L2_CID_PRIVATE_BASE + 5) +#define V4L2_CID_OVERLAY_VADDR0 (V4L2_CID_PRIVATE_BASE + 6) +#define V4L2_CID_OVERLAY_VADDR1 (V4L2_CID_PRIVATE_BASE + 7) +#define V4L2_CID_OVERLAY_VADDR2 (V4L2_CID_PRIVATE_BASE + 8) +#define V4L2_CID_OVLY_MODE (V4L2_CID_PRIVATE_BASE + 9) +#define V4L2_CID_DST_INFO (V4L2_CID_PRIVATE_BASE + 10) +/* UMP secure id control */ +#define V4L2_CID_GET_UMP_SECURE_ID (V4L2_CID_PRIVATE_BASE + 11) +#define V4L2_CID_GET_PHY_SRC_YADDR (V4L2_CID_PRIVATE_BASE + 12) +#define V4L2_CID_GET_PHY_SRC_CADDR (V4L2_CID_PRIVATE_BASE + 13) +#define V4L2_CID_IMAGE_EFFECT_FN (V4L2_CID_PRIVATE_BASE + 16) +#define V4L2_CID_IMAGE_EFFECT_APPLY (V4L2_CID_PRIVATE_BASE + 17) +#define V4L2_CID_IMAGE_EFFECT_CB (V4L2_CID_PRIVATE_BASE + 18) +#define V4L2_CID_IMAGE_EFFECT_CR (V4L2_CID_PRIVATE_BASE + 19) +#define V4L2_CID_RESERVED_MEM_BASE_ADDR (V4L2_CID_PRIVATE_BASE + 20) +#define V4L2_CID_FIMC_VERSION (V4L2_CID_PRIVATE_BASE + 21) + +#define V4L2_CID_CACHE_FLUSH (V4L2_CID_PRIVATE_BASE + 61) +#define V4L2_CID_RESERVED_MEM_SIZE (V4L2_CID_PRIVATE_BASE + 63) +#define V4L2_CID_STREAM_PAUSE (V4L2_CID_PRIVATE_BASE + 53) +#define V4L2_CID_CACHE_FLUSH (V4L2_CID_PRIVATE_BASE + 61) +#define V4L2_CID_RESERVED_MEM_SIZE (V4L2_CID_PRIVATE_BASE + 63) + +/* CID Extensions for camera sensor operations */ +#define V4L2_CID_CAM_PREVIEW_ONOFF (V4L2_CID_PRIVATE_BASE + 64) +#define V4L2_CID_CAM_CAPTURE (V4L2_CID_PRIVATE_BASE + 65) +/* #define V4L2_CID_CAM_JPEG_MEMSIZE (V4L2_CID_PRIVATE_BASE + 66) */ + +#define V4L2_CID_CAM_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 14) +#define V4L2_CID_CAM_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 15) +#define V4L2_CID_CAM_DATE_INFO_DATE (V4L2_CID_PRIVATE_BASE + 22) +#define V4L2_CID_CAM_SENSOR_VER (V4L2_CID_PRIVATE_BASE + 23) +#define V4L2_CID_CAM_FW_MINOR_VER (V4L2_CID_PRIVATE_BASE + 24) +#define V4L2_CID_CAM_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 25) +#define V4L2_CID_CAM_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 26) +#define V4L2_CID_CAM_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 27) +#define V4L2_CID_CAM_FW_VER (V4L2_CID_PRIVATE_BASE + 28) +#define V4L2_CID_CAM_SET_FW_ADDR (V4L2_CID_PRIVATE_BASE + 29) +#define V4L2_CID_CAM_SET_FW_SIZE (V4L2_CID_PRIVATE_BASE + 30) +#define V4L2_CID_CAM_UPDATE_FW (V4L2_CID_PRIVATE_BASE + 31) +enum v4l2_firmware_mode { + FW_MODE_NONE, + FW_MODE_VERSION, + FW_MODE_UPDATE, + FW_MODE_DUMP, +}; + +#define V4L2_CID_CAM_JPEG_MAIN_SIZE (V4L2_CID_PRIVATE_BASE + 32) +#define V4L2_CID_CAM_JPEG_MAIN_OFFSET (V4L2_CID_PRIVATE_BASE + 33) +#define V4L2_CID_CAM_JPEG_THUMB_SIZE (V4L2_CID_PRIVATE_BASE + 34) +#define V4L2_CID_CAM_JPEG_THUMB_OFFSET (V4L2_CID_PRIVATE_BASE + 35) +#define V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET (V4L2_CID_PRIVATE_BASE + 36) +#define V4L2_CID_CAM_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 37) +#define V4L2_CID_CAM_SENSOR_MAKER (V4L2_CID_PRIVATE_BASE + 38) +#define V4L2_CID_CAM_SENSOR_OPTICAL (V4L2_CID_PRIVATE_BASE + 39) +#define V4L2_CID_CAM_AF_VER_LOW (V4L2_CID_PRIVATE_BASE + 40) +#define V4L2_CID_CAM_AF_VER_HIGH (V4L2_CID_PRIVATE_BASE + 41) +#define V4L2_CID_CAM_GAMMA_RG_LOW (V4L2_CID_PRIVATE_BASE + 42) +#define V4L2_CID_CAM_GAMMA_RG_HIGH (V4L2_CID_PRIVATE_BASE + 43) +#define V4L2_CID_CAM_GAMMA_BG_LOW (V4L2_CID_PRIVATE_BASE + 44) +#define V4L2_CID_CAM_GAMMA_BG_HIGH (V4L2_CID_PRIVATE_BASE + 45) +#define V4L2_CID_CAM_DUMP_FW (V4L2_CID_PRIVATE_BASE + 46) +#define V4L2_CID_CAM_GET_DUMP_SIZE (V4L2_CID_PRIVATE_BASE + 47) +#define V4L2_CID_CAMERA_VT_MODE (V4L2_CID_PRIVATE_BASE + 48) +enum cam_vt_mode { + CAM_VT_MODE_NONE , + CAM_VT_MODE_3G , + CAM_VT_MODE_VOIP , +}; + +#define V4L2_CID_CAMERA_VGA_BLUR (V4L2_CID_PRIVATE_BASE + 49) +#define V4L2_CID_CAMERA_CAPTURE (V4L2_CID_PRIVATE_BASE + 50) +#define V4L2_CID_CAMERA_HDR (V4L2_CID_PRIVATE_BASE + 51) +#define V4L2_CID_CAMERA_HYBRID (V4L2_CID_PRIVATE_BASE + 52) + +#define V4L2_CID_MAIN_SW_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 54) +#define V4L2_CID_MAIN_SW_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 55) +#define V4L2_CID_MAIN_SW_DATE_INFO_DATE (V4L2_CID_PRIVATE_BASE + 56) +#define V4L2_CID_MAIN_SW_FW_MINOR_VER (V4L2_CID_PRIVATE_BASE + 57) +#define V4L2_CID_MAIN_SW_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 58) +#define V4L2_CID_MAIN_SW_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 59) +#define V4L2_CID_MAIN_SW_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 60) +#define V4L2_CID_CAMERA_HYBRID_CAPTURE (V4L2_CID_PRIVATE_BASE + 62) +#define V4L2_CID_CAMERA_FAST_MODE (V4L2_CID_PRIVATE_BASE + 66) +enum cam_fast_mode { + FAST_MODE_SUBSAMPLING_NONE , + FAST_MODE_SUBSAMPLING_HALF , + FAST_MODE_SUBSAMPLING_QUARTER , +}; +#define V4L2_CID_CAMERA_POSTVIEW_CAPTURE (V4L2_CID_PRIVATE_BASE + 67) +#define V4L2_CID_CAMERA_CAPTURE_MODE (V4L2_CID_PRIVATE_BASE + 68) +#define V4L2_CID_CAMERA_YUV_CAPTURE (V4L2_CID_PRIVATE_BASE + 69) + +#define V4L2_CID_FIMC_IS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x1000) +#define V4L2_CID_FIMC_IS_TUNE_BASE (V4L2_CTRL_CLASS_CAMERA | 0x2000) +#define V4L2_CID_FIMC_IS_ISP_DBG_BASE (V4L2_CTRL_CLASS_CAMERA | 0x3000) + +#define V4L2_CID_IS_LOAD_FW (V4L2_CID_FIMC_IS_BASE + 10) +#define V4L2_CID_IS_INIT_PARAM (V4L2_CID_FIMC_IS_BASE + 11) +#define V4L2_CID_IS_RESET (V4L2_CID_FIMC_IS_BASE + 12) +#define V4L2_CID_IS_S_POWER (V4L2_CID_FIMC_IS_BASE + 13) +enum is_set_power { + IS_POWER_OFF, + IS_POWER_ON +}; + +#define V4L2_CID_IS_S_STREAM (V4L2_CID_FIMC_IS_BASE + 14) +enum is_set_stream { + IS_DISABLE_STREAM, + IS_ENABLE_STREAM +}; + +#define V4L2_CID_IS_S_SCENARIO_MODE (V4L2_CID_FIMC_IS_BASE + 15) +#define V4L2_CID_IS_S_FORMAT_SCENARIO (V4L2_CID_FIMC_IS_BASE + 16) +enum scenario_mode { + IS_MODE_PREVIEW_STILL, + IS_MODE_PREVIEW_VIDEO, + IS_MODE_CAPTURE_STILL, + IS_MODE_CAPTURE_VIDEO, + IS_MODE_MAX +}; + +/* global */ +#define V4L2_CID_IS_CAMERA_SHOT_MODE_NORMAL (V4L2_CID_FIMC_IS_BASE + 400) +/* value : 1 : single shot , >=2 : continuous shot */ + +#define V4L2_CID_IS_CAMERA_SENSOR_NUM (V4L2_CID_FIMC_IS_BASE + 201) + +#define V4L2_CID_IS_CAMERA_FOCUS_MODE (V4L2_CID_FIMC_IS_BASE + 401) +enum is_focus_mode { + IS_FOCUS_MODE_AUTO, + IS_FOCUS_MODE_MACRO, + IS_FOCUS_MODE_INFINITY, + IS_FOCUS_MODE_CONTINUOUS, + IS_FOCUS_MODE_TOUCH, + IS_FOCUS_MODE_FACEDETECT, + IS_FOCUS_MODE_IDLE, + IS_FOCUS_MODE_MAX, +}; + +#define V4L2_CID_IS_CAMERA_FLASH_MODE (V4L2_CID_FIMC_IS_BASE + 402) +enum is_flash_mode { + IS_FLASH_MODE_OFF, + IS_FLASH_MODE_AUTO, + IS_FLASH_MODE_AUTO_REDEYE, + IS_FLASH_MODE_ON, + IS_FLASH_MODE_TORCH, + IS_FLASH_MODE_MAX +}; + +#define V4L2_CID_IS_CAMERA_AWB_MODE (V4L2_CID_FIMC_IS_BASE + 403) +enum is_awb_mode { + IS_AWB_AUTO, + IS_AWB_DAYLIGHT, + IS_AWB_CLOUDY, + IS_AWB_TUNGSTEN, + IS_AWB_FLUORESCENT, + IS_AWB_MAX +}; + +#define V4L2_CID_IS_CAMERA_IMAGE_EFFECT (V4L2_CID_FIMC_IS_BASE + 404) +enum is_image_effect { + IS_IMAGE_EFFECT_DISABLE, + IS_IMAGE_EFFECT_MONOCHROME, + IS_IMAGE_EFFECT_NEGATIVE_MONO, + IS_IMAGE_EFFECT_NEGATIVE_COLOR, + IS_IMAGE_EFFECT_SEPIA, + IS_IMAGE_EFFECT_SEPIA_CB, + IS_IMAGE_EFFECT_SEPIA_CR, + IS_IMAGE_EFFECT_NEGATIVE, + IS_IMAGE_EFFECT_ARTFREEZE, + IS_IMAGE_EFFECT_EMBOSSING, + IS_IMAGE_EFFECT_SILHOUETTE, + IS_IMAGE_EFFECT_MAX +}; + +#define V4L2_CID_IS_CAMERA_ISO (V4L2_CID_FIMC_IS_BASE + 405) +enum is_iso { + IS_ISO_AUTO, + IS_ISO_50, + IS_ISO_100, + IS_ISO_200, + IS_ISO_400, + IS_ISO_800, + IS_ISO_1600, + IS_ISO_MAX +}; + +#define V4L2_CID_IS_CAMERA_CONTRAST (V4L2_CID_FIMC_IS_BASE + 406) +enum is_contrast { + IS_CONTRAST_AUTO, + IS_CONTRAST_MINUS_2, + IS_CONTRAST_MINUS_1, + IS_CONTRAST_DEFAULT, + IS_CONTRAST_PLUS_1, + IS_CONTRAST_PLUS_2, + IS_CONTRAST_MAX +}; + +#define V4L2_CID_IS_CAMERA_SATURATION (V4L2_CID_FIMC_IS_BASE + 407) +enum is_saturation { + IS_SATURATION_MINUS_2, + IS_SATURATION_MINUS_1, + IS_SATURATION_DEFAULT, + IS_SATURATION_PLUS_1, + IS_SATURATION_PLUS_2, + IS_SATURATION_MAX +}; + +#define V4L2_CID_IS_CAMERA_SHARPNESS (V4L2_CID_FIMC_IS_BASE + 408) +enum is_sharpness { + IS_SHARPNESS_MINUS_2, + IS_SHARPNESS_MINUS_1, + IS_SHARPNESS_DEFAULT, + IS_SHARPNESS_PLUS_1, + IS_SHARPNESS_PLUS_2, + IS_SHARPNESS_MAX +}; + +#define V4L2_CID_IS_CAMERA_EXPOSURE (V4L2_CID_FIMC_IS_BASE + 409) +enum is_exposure { + IS_EXPOSURE_MINUS_4, + IS_EXPOSURE_MINUS_3, + IS_EXPOSURE_MINUS_2, + IS_EXPOSURE_MINUS_1, + IS_EXPOSURE_DEFAULT, + IS_EXPOSURE_PLUS_1, + IS_EXPOSURE_PLUS_2, + IS_EXPOSURE_PLUS_3, + IS_EXPOSURE_PLUS_4, + IS_EXPOSURE_MAX +}; + +#define V4L2_CID_IS_CAMERA_BRIGHTNESS (V4L2_CID_FIMC_IS_BASE + 410) +enum is_brightness { + IS_BRIGHTNESS_MINUS_2, + IS_BRIGHTNESS_MINUS_1, + IS_BRIGHTNESS_DEFAULT, + IS_BRIGHTNESS_PLUS_1, + IS_BRIGHTNESS_PLUS_2, + IS_BRIGHTNESS_MAX +}; + +#define V4L2_CID_IS_CAMERA_HUE (V4L2_CID_FIMC_IS_BASE + 411) +enum is_hue { + IS_HUE_MINUS_2, + IS_HUE_MINUS_1, + IS_HUE_DEFAULT, + IS_HUE_PLUS_1, + IS_HUE_PLUS_2, + IS_HUE_MAX +}; + +#define V4L2_CID_IS_CAMERA_METERING (V4L2_CID_FIMC_IS_BASE + 412) +enum is_metering { + IS_METERING_AVERAGE, + IS_METERING_SPOT, + IS_METERING_MATRIX, + IS_METERING_CENTER, + IS_METERING_MAX +}; +#define V4L2_CID_IS_CAMERA_METERING_POSITION_X (V4L2_CID_FIMC_IS_BASE + 500) +#define V4L2_CID_IS_CAMERA_METERING_POSITION_Y (V4L2_CID_FIMC_IS_BASE + 501) +#define V4L2_CID_IS_CAMERA_METERING_WINDOW_X (V4L2_CID_FIMC_IS_BASE + 502) +#define V4L2_CID_IS_CAMERA_METERING_WINDOW_Y (V4L2_CID_FIMC_IS_BASE + 503) + +#define V4L2_CID_IS_CAMERA_AFC_MODE (V4L2_CID_FIMC_IS_BASE + 413) +enum is_afc_mode { + IS_AFC_DISABLE, + IS_AFC_AUTO, + IS_AFC_MANUAL_50HZ, + IS_AFC_MANUAL_60HZ, + IS_AFC_MAX +}; + +#define V4L2_CID_IS_AWB_LOCK_UNLOCK (V4L2_CID_FIMC_IS_BASE + 496) +enum is_awb_lock_unlock { + IS_AWB_LOCK, + IS_AWB_UNLOCK, + IS_AWB_LOCK_UNLOCK_MAX +}; + +#define V4L2_CID_IS_AE_LOCK_UNLOCK (V4L2_CID_FIMC_IS_BASE + 497) +enum is_ae_lock_unlock { + IS_AE_LOCK, + IS_AE_UNLOCK, + IS_AE_LOCK_UNLOCK_MAX +}; + +#define V4L2_CID_IS_FD_GET_FACE_COUNT (V4L2_CID_FIMC_IS_BASE + 600) +#define V4L2_CID_IS_FD_GET_FACE_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 601) +#define V4L2_CID_IS_FD_GET_FACE_CONFIDENCE (V4L2_CID_FIMC_IS_BASE + 602) +#define V4L2_CID_IS_FD_GET_FACE_SMILE_LEVEL (V4L2_CID_FIMC_IS_BASE + 603) +#define V4L2_CID_IS_FD_GET_FACE_BLINK_LEVEL (V4L2_CID_FIMC_IS_BASE + 604) +#define V4L2_CID_IS_FD_GET_FACE_TOPLEFT_X (V4L2_CID_FIMC_IS_BASE + 605) +#define V4L2_CID_IS_FD_GET_FACE_TOPLEFT_Y (V4L2_CID_FIMC_IS_BASE + 606) +#define V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_X (V4L2_CID_FIMC_IS_BASE + 607) +#define V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_Y (V4L2_CID_FIMC_IS_BASE + 608) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_X (V4L2_CID_FIMC_IS_BASE + 609) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_Y (V4L2_CID_FIMC_IS_BASE + 610) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_X (V4L2_CID_FIMC_IS_BASE + 611) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_Y (V4L2_CID_FIMC_IS_BASE + 612) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_X (V4L2_CID_FIMC_IS_BASE + 613) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_Y (V4L2_CID_FIMC_IS_BASE + 614) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_X (V4L2_CID_FIMC_IS_BASE + 615) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_Y (V4L2_CID_FIMC_IS_BASE + 616) +#define V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_X (V4L2_CID_FIMC_IS_BASE + 617) +#define V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_Y (V4L2_CID_FIMC_IS_BASE + 618) +#define V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_X (V4L2_CID_FIMC_IS_BASE + 619) +#define V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_Y (V4L2_CID_FIMC_IS_BASE + 620) +#define V4L2_CID_IS_FD_GET_ANGLE (V4L2_CID_FIMC_IS_BASE + 621) +#define V4L2_CID_IS_FD_GET_YAW_ANGLE (V4L2_CID_FIMC_IS_BASE + 622) +#define V4L2_CID_IS_FD_GET_NEXT (V4L2_CID_FIMC_IS_BASE + 623) +#define V4L2_CID_IS_FD_GET_DATA (V4L2_CID_FIMC_IS_BASE + 624) + +#define V4L2_CID_IS_FD_SET_MAX_FACE_NUMBER (V4L2_CID_FIMC_IS_BASE + 650) +#define V4L2_CID_IS_FD_SET_ROLL_ANGLE (V4L2_CID_FIMC_IS_BASE + 651) + +enum is_fd_roll_angle { + /* 0, 45, 0, -45 */ + IS_FD_ROLL_ANGLE_BASIC = 0, + /* 0, 30, 0, -30, 0, 45, 0, -45 */ + IS_FD_ROLL_ANGLE_PRECISE_BASIC = 1, + /* 0, 90, 0, -90 */ + IS_FD_ROLL_ANGLE_SIDES = 2, + /* 0, 90, 0, -90 0, 45, 0, -45 */ + IS_FD_ROLL_ANGLE_PRECISE_SIDES = 3, + /* 0, 90, 0, -90, 0, 180 */ + IS_FD_ROLL_ANGLE_FULL = 4, + /* 0, 90, 0, -90, 0, 180, 0, 135, 0, -135 */ + IS_FD_ROLL_ANGLE_PRECISE_FULL = 5, +}; + +#define V4L2_CID_IS_FD_SET_YAW_ANGLE (V4L2_CID_FIMC_IS_BASE + 652) +enum is_fd_yaw_angle { + IS_FD_YAW_ANGLE_0 = 0, + IS_FD_YAW_ANGLE_45 = 1, + IS_FD_YAW_ANGLE_90 = 2, + IS_FD_YAW_ANGLE_45_90 = 3, +}; + +#define V4L2_CID_IS_FD_SET_SMILE_MODE (V4L2_CID_FIMC_IS_BASE + 653) +enum is_fd_smile_mode { + IS_FD_SMILE_MODE_DISABLE = 0, + IS_FD_SMILE_MODE_ENABLE = 1, +}; + +#define V4L2_CID_IS_FD_SET_BLINK_MODE (V4L2_CID_FIMC_IS_BASE + 654) +enum is_fd_blink_mode { + IS_FD_BLINK_MODE_DISABLE = 0, + IS_FD_BLINK_MODE_ENABLE = 1, +}; + +#define V4L2_CID_IS_FD_SET_EYE_DETECT_MODE (V4L2_CID_FIMC_IS_BASE + 655) +enum is_fd_eye_detect_mode { + IS_FD_EYE_DETECT_DISABLE = 0, + IS_FD_EYE_DETECT_ENABLE = 1, +}; + +#define V4L2_CID_IS_FD_SET_MOUTH_DETECT_MODE (V4L2_CID_FIMC_IS_BASE + 656) +enum is_fd_mouth_detect_mode { + IS_FD_MOUTH_DETECT_DISABLE = 0, + IS_FD_MOUTH_DETECT_ENABLE = 1, +}; + +#define V4L2_CID_IS_FD_SET_ORIENTATION_MODE (V4L2_CID_FIMC_IS_BASE + 657) +enum is_fd_orientation_mode { + IS_FD_ORIENTATION_DISABLE = 0, + IS_FD_ORIENTATION_ENABLE = 1, +}; + +#define V4L2_CID_IS_FD_SET_ORIENTATION (V4L2_CID_FIMC_IS_BASE + 658) +#define V4L2_CID_IS_FD_SET_DATA_ADDRESS (V4L2_CID_FIMC_IS_BASE + 659) + +#define V4L2_CID_IS_SET_ISP (V4L2_CID_FIMC_IS_BASE + 440) +enum is_isp_bypass_mode { + IS_ISP_BYPASS_DISABLE, + IS_ISP_BYPASS_ENABLE, + IS_ISP_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_DRC (V4L2_CID_FIMC_IS_BASE + 441) +enum is_drc_bypass_mode { + IS_DRC_BYPASS_DISABLE, + IS_DRC_BYPASS_ENABLE, + IS_DRC_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_FD (V4L2_CID_FIMC_IS_BASE + 442) +enum is_fd_bypass_mode { + IS_FD_BYPASS_DISABLE, + IS_FD_BYPASS_ENABLE, + IS_FD_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_ODC (V4L2_CID_FIMC_IS_BASE + 443) +enum is_odc_bypass_mode { + IS_ODC_BYPASS_DISABLE, + IS_ODC_BYPASS_ENABLE, + IS_ODC_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_DIS (V4L2_CID_FIMC_IS_BASE + 444) +enum is_dis_bypass_mode { + IS_DIS_BYPASS_DISABLE, + IS_DIS_BYPASS_ENABLE, + IS_DIS_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_3DNR (V4L2_CID_FIMC_IS_BASE + 445) +enum is_tdnr_bypass_mode { + IS_TDNR_BYPASS_DISABLE, + IS_TDNR_BYPASS_ENABLE, + IS_TDNR_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_SCALERC (V4L2_CID_FIMC_IS_BASE + 446) +enum is_scalerc_bypass_mode { + IS_SCALERC_BYPASS_DISABLE, + IS_SCALERC_BYPASS_ENABLE, + IS_SCALERC_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_SCALERP (V4L2_CID_FIMC_IS_BASE + 446) +enum is_scalerp_bypass_mode { + IS_SCALERP_BYPASS_DISABLE, + IS_SCALERP_BYPASS_ENABLE, + IS_SCALERP_BYPASS_MAX +}; + +#define V4L2_CID_IS_ROTATION_MODE (V4L2_CID_FIMC_IS_BASE + 450) +enum is_rotation_mode { + IS_ROTATION_0, + IS_ROTATION_90, + IS_ROTATION_180, + IS_ROTATION_270, + IS_ROTATION_MAX +}; + +#define V4L2_CID_IS_3DNR_1ST_FRAME_MODE (V4L2_CID_FIMC_IS_BASE + 451) +enum is_tdnr_1st_frame_mode { + IS_TDNR_1ST_FRAME_NOPROCESSING, + IS_TDNR_1ST_FRAME_2DNR, + IS_TDNR_MAX +}; + +#define V4L2_CID_IS_CAMERA_OBJECT_POSITION_X (V4L2_CID_FIMC_IS_BASE + 452) +#define V4L2_CID_IS_CAMERA_OBJECT_POSITION_Y (V4L2_CID_FIMC_IS_BASE + 453) +#define V4L2_CID_IS_CAMERA_WINDOW_SIZE_X (V4L2_CID_FIMC_IS_BASE + 454) +#define V4L2_CID_IS_CAMERA_WINDOW_SIZE_Y (V4L2_CID_FIMC_IS_BASE + 455) + +#define V4L2_CID_IS_CAMERA_EXIF_EXPTIME (V4L2_CID_FIMC_IS_BASE + 456) +#define V4L2_CID_IS_CAMERA_EXIF_FLASH (V4L2_CID_FIMC_IS_BASE + 457) +#define V4L2_CID_IS_CAMERA_EXIF_ISO (V4L2_CID_FIMC_IS_BASE + 458) +#define V4L2_CID_IS_CAMERA_EXIF_SHUTTERSPEED (V4L2_CID_FIMC_IS_BASE + 459) +#define V4L2_CID_IS_CAMERA_EXIF_BRIGHTNESS (V4L2_CID_FIMC_IS_BASE + 460) + +#define V4L2_CID_IS_CAMERA_ISP_SEL_INPUT (V4L2_CID_FIMC_IS_BASE + 461) +enum is_isp_sel_input { + IS_ISP_INPUT_OTF, + IS_ISP_INPUT_DMA1, + IS_ISP_INPUT_DMA2, + IS_ISP_INPUT_DMA12, + IS_ISP_INPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_ISP_SEL_OUTPUT (V4L2_CID_FIMC_IS_BASE + 462) +enum is_isp_sel_output { + IS_ISP_OUTPUT_OTF, + IS_ISP_OUTPUT_DMA1, + IS_ISP_OUTPUT_DMA2, + IS_ISP_OUTPUT_DMA12, + IS_ISP_OUTPUT_OTF_DMA1, + IS_ISP_OUTPUT_OTF_DMA2, + IS_ISP_OUTPUT_OTF_DMA12, + IS_ISP_OUTPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_DRC_SEL_INPUT (V4L2_CID_FIMC_IS_BASE + 463) +enum is_drc_sel_input { + IS_DRC_INPUT_OTF, + IS_DRC_INPUT_DMA, + IS_DRC_INPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_FD_SEL_INPUT (V4L2_CID_FIMC_IS_BASE + 464) +enum is_fd_sel_input { + IS_FD_INPUT_OTF, + IS_FD_INPUT_DMA, + IS_FD_INPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_INIT_WIDTH (V4L2_CID_FIMC_IS_BASE + 465) +#define V4L2_CID_IS_CAMERA_INIT_HEIGHT (V4L2_CID_FIMC_IS_BASE + 466) + +#define V4L2_CID_IS_CMD_ISP (V4L2_CID_FIMC_IS_BASE + 467) +enum is_isp_cmd_mode { + IS_ISP_COMMAND_STOP, + IS_ISP_COMMAND_START, + IS_ISP_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_DRC (V4L2_CID_FIMC_IS_BASE + 468) +enum is_drc_cmd_mode { + IS_DRC_COMMAND_STOP, + IS_DRC_COMMAND_START, + IS_DRC_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_FD (V4L2_CID_FIMC_IS_BASE + 469) +enum is_fd_cmd_mode { + IS_FD_COMMAND_STOP, + IS_FD_COMMAND_START, + IS_FD_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_ODC (V4L2_CID_FIMC_IS_BASE + 470) +enum is_odc_cmd_mode { + IS_ODC_COMMAND_STOP, + IS_ODC_COMMAND_START, + IS_ODC_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_DIS (V4L2_CID_FIMC_IS_BASE + 471) +enum is_dis_cmd_mode { + IS_DIS_COMMAND_STOP, + IS_DIS_COMMAND_START, + IS_DIS_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_TDNR (V4L2_CID_FIMC_IS_BASE + 472) +enum is_tdnr_cmd_mode { + IS_TDNR_COMMAND_STOP, + IS_TDNR_COMMAND_START, + IS_TDNR_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_SCALERC (V4L2_CID_FIMC_IS_BASE + 473) +enum is_scalerc_cmd_mode { + IS_SCALERC_COMMAND_STOP, + IS_SCALERC_COMMAND_START, + IS_SCALERC_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_SCALERP (V4L2_CID_FIMC_IS_BASE + 474) +enum is_scalerp_cmd_mode { + IS_SCALERP_COMMAND_STOP, + IS_SCALERP_COMMAND_START, + IS_SCALERP_COMMAND_MAX +}; + +#define V4L2_CID_IS_GET_SENSOR_OFFSET_X (V4L2_CID_FIMC_IS_BASE + 480) +#define V4L2_CID_IS_GET_SENSOR_OFFSET_Y (V4L2_CID_FIMC_IS_BASE + 481) +#define V4L2_CID_IS_GET_SENSOR_WIDTH (V4L2_CID_FIMC_IS_BASE + 482) +#define V4L2_CID_IS_GET_SENSOR_HEIGHT (V4L2_CID_FIMC_IS_BASE + 483) + +#define V4L2_CID_IS_GET_FRAME_VALID (V4L2_CID_FIMC_IS_BASE + 484) +#define V4L2_CID_IS_SET_FRAME_VALID (V4L2_CID_FIMC_IS_BASE + 485) +#define V4L2_CID_IS_GET_FRAME_BADMARK (V4L2_CID_FIMC_IS_BASE + 486) +#define V4L2_CID_IS_SET_FRAME_BADMARK (V4L2_CID_FIMC_IS_BASE + 487) +#define V4L2_CID_IS_GET_FRAME_CAPTURED (V4L2_CID_FIMC_IS_BASE + 488) +#define V4L2_CID_IS_SET_FRAME_CAPTURED (V4L2_CID_FIMC_IS_BASE + 489) +#define V4L2_CID_IS_SET_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 490) +#define V4L2_CID_IS_GET_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 491) +#define V4L2_CID_IS_CLEAR_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 492) +#define V4L2_CID_IS_GET_LOSTED_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 493) +#define V4L2_CID_IS_ISP_DMA_BUFFER_NUM (V4L2_CID_FIMC_IS_BASE + 494) +#define V4L2_CID_IS_ISP_DMA_BUFFER_ADDRESS (V4L2_CID_FIMC_IS_BASE + 495) + +#define V4L2_CID_IS_ZOOM_STATE (V4L2_CID_FIMC_IS_BASE + 660) +#define V4L2_CID_IS_ZOOM_MAX_LEVEL (V4L2_CID_FIMC_IS_BASE + 661) +#define V4L2_CID_IS_ZOOM (V4L2_CID_FIMC_IS_BASE + 662) +#define V4L2_CID_IS_FW_DEBUG_REGION_ADDR (V4L2_CID_FIMC_IS_BASE + 663) + +#define V4L2_CID_IS_TUNE_SEL_ENTRY (V4L2_CID_FIMC_IS_TUNE_BASE) +#define V4L2_CID_IS_TUNE_SENSOR_EXPOSURE (V4L2_CID_FIMC_IS_TUNE_BASE + 1) +#define V4L2_CID_IS_TUNE_SENSOR_ANALOG_GAIN (V4L2_CID_FIMC_IS_TUNE_BASE + 2) +#define V4L2_CID_IS_TUNE_SENSOR_FRAME_RATE (V4L2_CID_FIMC_IS_TUNE_BASE + 3) +#define V4L2_CID_IS_TUNE_SENSOR_ACTUATOR_POS (V4L2_CID_FIMC_IS_TUNE_BASE + 4) + +enum v4l2_blur { + BLUR_LEVEL_0 = 0, + BLUR_LEVEL_1, + BLUR_LEVEL_2, + BLUR_LEVEL_3, + BLUR_LEVEL_MAX, +}; + +#if 1 +#define V4L2_CID_CAMERA_SCENE_MODE (V4L2_CID_PRIVATE_BASE+70) +enum v4l2_scene_mode { + SCENE_MODE_BASE, + SCENE_MODE_NONE, + SCENE_MODE_PORTRAIT, + SCENE_MODE_NIGHTSHOT, + SCENE_MODE_BACK_LIGHT, + SCENE_MODE_LANDSCAPE, + SCENE_MODE_SPORTS, + SCENE_MODE_PARTY_INDOOR, + SCENE_MODE_BEACH_SNOW, + SCENE_MODE_SUNSET, + SCENE_MODE_DUSK_DAWN, + SCENE_MODE_FALL_COLOR, + SCENE_MODE_FIREWORKS, + SCENE_MODE_TEXT, + SCENE_MODE_CANDLE_LIGHT, + SCENE_MODE_LOW_LIGHT, + SCENE_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_FLASH_MODE (V4L2_CID_PRIVATE_BASE+71) +enum v4l2_flash_mode { + FLASH_MODE_BASE, + FLASH_MODE_OFF, + FLASH_MODE_AUTO, + FLASH_MODE_ON, + FLASH_MODE_TORCH, + FLASH_MODE_RED_EYE, + FLASH_MODE_FILL_IN, + FLASH_MODE_SLOW_SYNC, + FLASH_MODE_RED_EYE_FIX, + FLASH_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_BRIGHTNESS (V4L2_CID_PRIVATE_BASE+72) +enum v4l2_ev_mode { + EV_MINUS_4 = -4, + EV_MINUS_3 = -3, + EV_MINUS_2 = -2, + EV_MINUS_1 = -1, + EV_DEFAULT = 0, + EV_PLUS_1 = 1, + EV_PLUS_2 = 2, + EV_PLUS_3 = 3, + EV_PLUS_4 = 4, + EV_MAX, + EV_MAX_V4L2 = EV_MAX, +}; + +enum v4l2_exposure { + EXPOSURE_MINUS_6 = -6, + EXPOSURE_MINUS_5 = -5, + EXPOSURE_MINUS_4 = -4, + EXPOSURE_MINUS_3 = -3, + EXPOSURE_MINUS_2 = -2, + EXPOSURE_MINUS_1 = -1, + EXPOSURE_DEFAULT = 0, + EXPOSURE_PLUS_1 = 1, + EXPOSURE_PLUS_2 = 2, + EXPOSURE_PLUS_3 = 3, + EXPOSURE_PLUS_4 = 4, + EXPOSURE_PLUS_5 = 5, + EXPOSURE_PLUS_6 = 6, + EXPOSURE_MAX, +}; + +#define V4L2_CID_CAMERA_WHITE_BALANCE (V4L2_CID_PRIVATE_BASE+73) +enum v4l2_wb_mode { + WHITE_BALANCE_BASE = 0, + WHITE_BALANCE_AUTO, + WHITE_BALANCE_SUNNY, + WHITE_BALANCE_CLOUDY, + WHITE_BALANCE_TUNGSTEN, + WHITE_BALANCE_FLUORESCENT, + WHITE_BALANCE_FLUORESCENT_H, + WHITE_BALANCE_FLUORESCENT_L, + WHITE_BALANCE_CUSTOM, + WHITE_BALANCE_K, + WHITE_BALANCE_INCANDESCENT, + WHITE_BALANCE_PROHIBITION, + WHITE_BALANCE_HORIZON, + WHITE_BALANCE_LEDLIGHT, + WHITE_BALANCE_MAX, +}; + +#define V4L2_CID_CAMERA_EFFECT (V4L2_CID_PRIVATE_BASE+74) +enum v4l2_effect_mode { + IMAGE_EFFECT_BASE = 0, + IMAGE_EFFECT_NONE, + IMAGE_EFFECT_BNW, + IMAGE_EFFECT_SEPIA, + IMAGE_EFFECT_AQUA, + IMAGE_EFFECT_ANTIQUE, + IMAGE_EFFECT_NEGATIVE, + IMAGE_EFFECT_SHARPEN, + IMAGE_EFFECT_SKETCH, + IMAGE_EFFECT_WASHED, + IMAGE_EFFECT_VINTAGE_WARM, + IMAGE_EFFECT_VINTAGE_COLD, + IMAGE_EFFECT_SOLARIZE, + IMAGE_EFFECT_POSTERIZE, + IMAGE_EFFECT_POINT_BLUE, + IMAGE_EFFECT_POINT_RED_YELLOW, + IMAGE_EFFECT_POINT_COLOR_3, + IMAGE_EFFECT_POINT_GREEN, + IMAGE_EFFECT_POINT_RED, + IMAGE_EFFECT_POINT_YELLOW, + IMAGE_EFFECT_CARTOONIZE, + IMAGE_EFFECT_MAX, +}; + +#define V4L2_CID_CAMERA_ISO (V4L2_CID_PRIVATE_BASE+75) +enum v4l2_iso_mode { + ISO_AUTO = 0, + ISO_50, + ISO_100, + ISO_200, + ISO_400, + ISO_800, + ISO_1600, + ISO_3200, + ISO_SPORTS, + ISO_NIGHT, + ISO_MOVIE, + ISO_MAX, +}; + +#define V4L2_CID_CAMERA_METERING (V4L2_CID_PRIVATE_BASE+76) +enum v4l2_metering_mode { + METERING_BASE = 0, + METERING_MATRIX, + METERING_CENTER, + METERING_SPOT, + METERING_MAX, +}; + +#define V4L2_CID_CAMERA_CONTRAST (V4L2_CID_PRIVATE_BASE+77) +enum v4l2_contrast_mode { + CONTRAST_MINUS_2 = 0, + CONTRAST_MINUS_1, + CONTRAST_DEFAULT, + CONTRAST_PLUS_1, + CONTRAST_PLUS_2, + CONTRAST_MAX, +}; + +#define V4L2_CID_CAMERA_SATURATION (V4L2_CID_PRIVATE_BASE+78) +enum v4l2_saturation_mode { + SATURATION_MINUS_2 = 0, + SATURATION_MINUS_1, + SATURATION_DEFAULT, + SATURATION_PLUS_1, + SATURATION_PLUS_2, + SATURATION_MAX, +}; + +#define V4L2_CID_CAMERA_SHARPNESS (V4L2_CID_PRIVATE_BASE+79) +enum v4l2_sharpness_mode { + SHARPNESS_MINUS_2 = 0, + SHARPNESS_MINUS_1, + SHARPNESS_DEFAULT, + SHARPNESS_PLUS_1, + SHARPNESS_PLUS_2, + SHARPNESS_MAX, +}; + +#define V4L2_CID_CAMERA_WDR (V4L2_CID_PRIVATE_BASE+80) +enum v4l2_wdr_mode { + WDR_OFF, + WDR_ON, + WDR_MAX, +}; + +#define V4L2_CID_CAMERA_ANTI_SHAKE (V4L2_CID_PRIVATE_BASE+81) +enum v4l2_anti_shake_mode { + ANTI_SHAKE_OFF, + ANTI_SHAKE_STILL_ON, + ANTI_SHAKE_MOVIE_ON, + ANTI_SHAKE_MAX, +}; + +#define V4L2_CID_CAMERA_TOUCH_AF_START_STOP (V4L2_CID_PRIVATE_BASE+82) +enum v4l2_touch_af { + TOUCH_AF_STOP = 0, + TOUCH_AF_START, + TOUCH_AF_MAX, +}; + +#define V4L2_CID_CAMERA_SMART_AUTO (V4L2_CID_PRIVATE_BASE+83) +enum v4l2_smart_auto { + SMART_AUTO_OFF = 0, + SMART_AUTO_ON, + SMART_AUTO_MAX, +}; + +#define V4L2_CID_CAMERA_VINTAGE_MODE (V4L2_CID_PRIVATE_BASE+84) +enum v4l2_vintage_mode { + VINTAGE_MODE_BASE, + VINTAGE_MODE_OFF, + VINTAGE_MODE_NORMAL, + VINTAGE_MODE_WARM, + VINTAGE_MODE_COOL, + VINTAGE_MODE_BNW, + VINTAGE_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE+85) +#define V4L2_CID_CAMERA_CAPTURE_THUMB (V4L2_CID_PRIVATE_BASE + 86) +#define V4L2_CID_CAMERA_YUV_SNAPSHOT (V4L2_CID_PRIVATE_BASE + 87) +#define V4L2_CID_CAMERA_LOW_LIGHT_MODE (V4L2_CID_PRIVATE_BASE + 88) +#define V4L2_CID_CAMERA_GPS_LATITUDE (V4L2_CID_CAMERA_CLASS_BASE+30) +/* (V4L2_CID_PRIVATE_BASE+87) */ +#define V4L2_CID_CAMERA_GPS_LONGITUDE (V4L2_CID_CAMERA_CLASS_BASE + 31) +/* (V4L2_CID_PRIVATE_BASE+88) */ +#define V4L2_CID_CAMERA_GPS_TIMESTAMP (V4L2_CID_CAMERA_CLASS_BASE + 32) +/* (V4L2_CID_PRIVATE_BASE+89)*/ +#define V4L2_CID_CAMERA_GPS_ALTITUDE (V4L2_CID_CAMERA_CLASS_BASE + 33) +#define V4L2_CID_CAMERA_EXIF_TIME_INFO (V4L2_CID_CAMERA_CLASS_BASE + 34) +#define V4L2_CID_CAMERA_GPS_PROCESSINGMETHOD (V4L2_CID_CAMERA_CLASS_BASE+35) + +#define V4L2_CID_FOCUS_AUTO_MODE (V4L2_CID_CAMERA_CLASS_BASE+36) +enum v4l2_focus_mode_type { + V4L2_FOCUS_AUTO_NORMAL = 0, + V4L2_FOCUS_AUTO_MACRO, + V4L2_FOCUS_AUTO_CONTINUOUS, + V4L2_FOCUS_AUTO_FACE_DETECTION, + V4L2_FOCUS_AUTO_RECTANGLE, + V4L2_FOCUS_AUTO_MAX, +}; +#define V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT (V4L2_CID_CAMERA_CLASS_BASE+37) +#define V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP (V4L2_CID_CAMERA_CLASS_BASE+38) +#define V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH (V4L2_CID_CAMERA_CLASS_BASE+39) +#define V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT (V4L2_CID_CAMERA_CLASS_BASE+40) + +#define V4L2_CID_CAMERA_ZOOM (V4L2_CID_PRIVATE_BASE+90) +enum v4l2_zoom_level { + ZOOM_LEVEL_0 = 0, + ZOOM_LEVEL_1, + ZOOM_LEVEL_2, + ZOOM_LEVEL_3, + ZOOM_LEVEL_4, + ZOOM_LEVEL_5, + ZOOM_LEVEL_6, + ZOOM_LEVEL_7, + ZOOM_LEVEL_8, + ZOOM_LEVEL_9, + ZOOM_LEVEL_10, + ZOOM_LEVEL_11, + ZOOM_LEVEL_12, + ZOOM_LEVEL_MAX = 31, +}; + +#define V4L2_CID_CAMERA_FACE_DETECTION (V4L2_CID_PRIVATE_BASE+91) +enum v4l2_face_detection { + FACE_DETECTION_OFF = 0, + FACE_DETECTION_ON, + FACE_DETECTION_NOLINE, + FACE_DETECTION_ON_BEAUTY, + FACE_DETECTION_NORMAL, + FACE_DETECTION_SMILE_SHOT, + FACE_DETECTION_BLINK, + FACE_DETECTION_MAX, +}; + +#define V4L2_CID_CAMERA_SMART_AUTO_STATUS (V4L2_CID_PRIVATE_BASE+92) +enum v4l2_smart_auto_status { + SMART_AUTO_STATUS_AUTO = 0, + SMART_AUTO_STATUS_LANDSCAPE, + SMART_AUTO_STATUS_PORTRAIT, + SMART_AUTO_STATUS_MACRO, + SMART_AUTO_STATUS_NIGHT, + SMART_AUTO_STATUS_PORTRAIT_NIGHT, + SMART_AUTO_STATUS_BACKLIT, + SMART_AUTO_STATUS_PORTRAIT_BACKLIT, + SMART_AUTO_STATUS_ANTISHAKE, + SMART_AUTO_STATUS_PORTRAIT_ANTISHAKE, + SMART_AUTO_STATUS_MAX, +}; + +#define V4L2_CID_CAMERA_SET_AUTO_FOCUS (V4L2_CID_PRIVATE_BASE+93) +enum v4l2_auto_focus { + AUTO_FOCUS_OFF = 0, + AUTO_FOCUS_ON, + AUTO_FOCUS_MAX, +}; + +#define V4L2_CID_CAMERA_BEAUTY_SHOT (V4L2_CID_PRIVATE_BASE+94) +enum v4l2_beauty_shot { + BEAUTY_SHOT_OFF = 0, + BEAUTY_SHOT_ON, + BEAUTY_SHOT_MAX, +}; + +#define V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK (V4L2_CID_PRIVATE_BASE+95) +enum v4l2_ae_awb_lockunlock { + AE_UNLOCK_AWB_UNLOCK = 0, + AE_LOCK_AWB_UNLOCK, + AE_UNLOCK_AWB_LOCK, + AE_LOCK_AWB_LOCK, + AE_AWB_MAX +}; + +#define V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK (V4L2_CID_PRIVATE_BASE+96) +enum v4l2_face_lock { + FACE_LOCK_OFF = 0, + FACE_LOCK_ON, + FIRST_FACE_TRACKING, + FACE_LOCK_MAX, +}; + +#define V4L2_CID_CAMERA_OBJECT_POSITION_X (V4L2_CID_PRIVATE_BASE+97) +#define V4L2_CID_CAMERA_OBJECT_POSITION_Y (V4L2_CID_PRIVATE_BASE+98) +#define V4L2_CID_CAMERA_FOCUS_MODE (V4L2_CID_PRIVATE_BASE+99) +enum v4l2_focusmode { + FOCUS_MODE_AUTO = 0, + FOCUS_MODE_MACRO, + FOCUS_MODE_FACEDETECT, + FOCUS_MODE_AUTO_DEFAULT, + FOCUS_MODE_MACRO_DEFAULT, + FOCUS_MODE_FACEDETECT_DEFAULT, + FOCUS_MODE_INFINITY, + FOCUS_MODE_FIXED, + FOCUS_MODE_CONTINOUS, + FOCUS_MODE_CONTINOUS_PICTURE, + FOCUS_MODE_CONTINOUS_PICTURE_MACRO, + FOCUS_MODE_CONTINOUS_VIDEO, + FOCUS_MODE_TOUCH, + FOCUS_MODE_MANUAL, + FOCUS_MODE_MULTI, + FOCUS_MODE_OBJECT_TRACKING, + FOCUS_MODE_MAX, + FOCUS_MODE_DEFAULT = (1 << 8), +}; + +#define V4L2_CID_CAMERA_OBJ_TRACKING_STATUS (V4L2_CID_PRIVATE_BASE+100) +enum v4l2_obj_tracking_status { + OBJECT_TRACKING_STATUS_BASE = 0, + OBJECT_TRACKING_STATUS_SUCCESS = 1, + OBJECT_TRACKING_STATUS_MISSING = 2, + OBJECT_TRACKING_STATUS_FAIL = 3, + OBJECT_TRACKING_STATUS_MAX, +}; + +#define V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP (V4L2_CID_PRIVATE_BASE+101) +enum v4l2_ot_start_stop { + OT_STOP = 0, + OT_START, + OT_MAX, +}; + +#define V4L2_CID_CAMERA_CAF_START_STOP (V4L2_CID_PRIVATE_BASE+102) +enum v4l2_caf_start_stop { + CAF_STOP = 0, + CAF_START, + CAF_MAX, +}; + +#define V4L2_CID_CAMERA_AUTO_FOCUS_RESULT (V4L2_CID_PRIVATE_BASE+103) +enum v4l2_af_status { + CAMERA_AF_STATUS_IN_PROGRESS = 0, + CAMERA_AF_STATUS_SUCCESS, + CAMERA_AF_STATUS_FAIL, + CAMERA_AF_STATUS_1ST_SUCCESS, + CAMERA_AF_STATUS_RESTART, + CAMERA_AF_STATUS_MAX, +}; + +#define V4L2_CID_CAMERA_FRAME_RATE (V4L2_CID_PRIVATE_BASE+104) +enum v4l2_frame_rate { + FRAME_RATE_AUTO = 0, + FRAME_RATE_7 = 7, + FRAME_RATE_15 = 15, + FRAME_RATE_20 = 20, + FRAME_RATE_25 = 25, + FRAME_RATE_30 = 30, + FRAME_RATE_60 = 60, + FRAME_RATE_120 = 120, + FRAME_RATE_MAX +}; + +#define V4L2_CID_CAMERA_ANTI_BANDING (V4L2_CID_PRIVATE_BASE+105) +enum v4l2_anti_banding { + ANTI_BANDING_AUTO = 0, + ANTI_BANDING_50HZ = 1, + ANTI_BANDING_60HZ = 2, + ANTI_BANDING_50_60Hz = 3, + ANTI_BANDING_OFF = 4, +}; + +#define V4L2_CID_CAMERA_SET_GAMMA (V4L2_CID_PRIVATE_BASE+106) +enum v4l2_gamma_mode { + GAMMA_OFF = 0, + GAMMA_ON = 1, + GAMMA_MAX, +}; + +#define V4L2_CID_CAMERA_SET_SLOW_AE (V4L2_CID_PRIVATE_BASE+107) +enum v4l2_slow_ae_mode { + SLOW_AE_OFF, + SLOW_AE_ON, + SLOW_AE_MAX, +}; + +#define V4L2_CID_CAMERA_BATCH_REFLECTION (V4L2_CID_PRIVATE_BASE+108) +#define V4L2_CID_CAMERA_EXIF_ORIENTATION (V4L2_CID_PRIVATE_BASE+109) +#define V4L2_CID_CAMERA_GET_LUX (V4L2_CID_PRIVATE_BASE+110) + +/* s1_camera [ Defense process by ESD input ] */ +#define V4L2_CID_CAMERA_RESET (V4L2_CID_PRIVATE_BASE+111) +#define V4L2_CID_CAMERA_CHECK_DATALINE (V4L2_CID_PRIVATE_BASE+112) +#define V4L2_CID_CAMERA_CHECK_DATALINE_STOP (V4L2_CID_PRIVATE_BASE+113) + +#endif + +/* Modify NTTS1 */ +#if defined(CONFIG_ARIES_NTT) +#define V4L2_CID_CAMERA_AE_AWB_DISABLE_LOCK (V4L2_CID_PRIVATE_BASE+114) +#endif +#define V4L2_CID_CAMERA_THUMBNAIL_NULL (V4L2_CID_PRIVATE_BASE+115) +#define V4L2_CID_CAMERA_SENSOR_MODE (V4L2_CID_PRIVATE_BASE+116) +enum v4l2_sensor_mode { + SENSOR_CAMERA, + SENSOR_MOVIE, +}; + +enum stream_mode_t { + STREAM_MODE_CAM_OFF, + STREAM_MODE_CAM_ON, + STREAM_MODE_MOVIE_OFF, + STREAM_MODE_MOVIE_ON, + STREAM_MODE_WAIT_OFF +}; + +#define V4L2_CID_CAMERA_EXIF_EXPTIME (V4L2_CID_PRIVATE_BASE+117) +#define V4L2_CID_CAMERA_EXIF_FLASH (V4L2_CID_PRIVATE_BASE+118) +#define V4L2_CID_CAMERA_EXIF_ISO (V4L2_CID_PRIVATE_BASE+119) +#define V4L2_CID_CAMERA_EXIF_TV (V4L2_CID_PRIVATE_BASE+120) +#define V4L2_CID_CAMERA_EXIF_BV (V4L2_CID_PRIVATE_BASE+121) +#define V4L2_CID_CAMERA_EXIF_EBV (V4L2_CID_PRIVATE_BASE+122) +#define V4L2_CID_CAMERA_CHECK_ESD (V4L2_CID_PRIVATE_BASE+123) +#define V4L2_CID_CAMERA_APP_CHECK (V4L2_CID_PRIVATE_BASE+124) +#define V4L2_CID_CAMERA_CHECK_SENSOR_STATUS (V4L2_CID_PRIVATE_BASE+150) +#define V4L2_CID_CAMERA_DEFAULT_FOCUS_POSITION (V4L2_CID_PRIVATE_BASE+151) +#define V4L2_CID_CAMERA_BUSFREQ_LOCK (V4L2_CID_PRIVATE_BASE+125) +#define V4L2_CID_CAMERA_BUSFREQ_UNLOCK (V4L2_CID_PRIVATE_BASE+126) + +/* If you would like to control AE and AWB lock with signle command, + * use V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK above. + */ +#define V4L2_CID_CAMERA_AE_LOCK_UNLOCK (V4L2_CID_PRIVATE_BASE + 127) +enum v4l2_ae_lockunlock { + AE_UNLOCK = 0, + AE_LOCK, + AE_LOCK_MAX +}; + +#define V4L2_CID_CAMERA_AWB_LOCK_UNLOCK (V4L2_CID_PRIVATE_BASE + 128) +enum v4l2_awb_lockunlock { + AWB_UNLOCK = 0, + AWB_LOCK, + AWB_LOCK_MAX +}; + +#define V4L2_CID_CAMERA_SENSOR_OUTPUT_SIZE (V4L2_CID_PRIVATE_BASE + 129) +#define V4L2_CID_EMBEDDEDDATA_ENABLE (V4L2_CID_PRIVATE_BASE + 130) +#define V4L2_CID_CAMERA_JPEG_RESOLUTION (V4L2_CID_PRIVATE_BASE + 131) +#define V4L2_CID_CAMERA_FACE_ZOOM (V4L2_CID_PRIVATE_BASE + 132) +enum v4l2_face_zoom { + FACE_ZOOM_STOP = 0, + FACE_ZOOM_START +}; + +/* control for post processing block in ISP */ +#define V4L2_CID_CAMERA_SET_ODC (V4L2_CID_PRIVATE_BASE+127) +enum set_odc_mode { + CAMERA_ODC_ON, + CAMERA_ODC_OFF +}; + +#define V4L2_CID_CAMERA_SET_DIS (V4L2_CID_PRIVATE_BASE+128) +enum set_dis_mode { + CAMERA_DIS_ON, + CAMERA_DIS_OFF +}; + +#define V4L2_CID_CAMERA_SET_3DNR (V4L2_CID_PRIVATE_BASE+129) +enum set_3dnr_mode { + CAMERA_3DNR_ON, + CAMERA_3DNR_OFF +}; + +#define V4L2_CID_CAMERA_BRACKET (V4L2_CID_PRIVATE_BASE+134) +enum v4l2_face_bracket_mode { + BRACKET_MODE_OFF = 0, + BRACKET_MODE_AEB, + BRACKET_MODE_WBB, + BRACKET_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_BRACKET_AEB (V4L2_CID_PRIVATE_BASE+135) +enum v4l2_face_bracket_aeb_value { + BRACKET_AEB_VALUE1 = 1, + BRACKET_AEB_VALUE2, + BRACKET_AEB_VALUE3, + BRACKET_AEB_VALUE4, + BRACKET_AEB_VALUE5, + BRACKET_AEB_VALUE6, +}; + +#define V4L2_CID_CAMERA_BRACKET_WBB (V4L2_CID_PRIVATE_BASE+136) +enum v4l2_face_bracket_wbb_value { + BRACKET_WBB_OFF = 0, + BRACKET_WBB_VALUE1 = 1, + BRACKET_WBB_VALUE2, + BRACKET_WBB_VALUE3, + BRACKET_WBB_VALUE4, + BRACKET_WBB_VALUE5, + BRACKET_WBB_VALUE6, +}; + +#define V4L2_CID_CAMERA_DRIVE_DIAL (V4L2_CID_PRIVATE_BASE+137) +enum v4l2_drive_dial { + DRIVEDIAL_SINGLE = 1, + DRIVEDIAL_BKT = 2, + DRIVEDIAL_CONTI_3 = 3, + DRIVEDIAL_CONTI_5 = 5, + DRIVEDIAL_CONTI_10 = 10, +}; + +enum v4l2_running_cap_mode { + RUNNING_MODE_SINGLE = 0, + RUNNING_MODE_CONTINUOUS, + RUNNING_MODE_BEST, + RUNNING_MODE_LOWLIGHT, + RUNNING_MODE_AE_BRACKET, + RUNNING_MODE_WB_BRACKET, + RUNNING_MODE_HDR, + RUNNING_MODE_BLINK, + RUNNING_MODE_RAW, + RUNNING_MODE_BURST, + RUNNING_MODE_MAX +}; + +enum v4l2_continuous_mode { + CONTINUOUS_MODE_OFF = 0, + CONTINUOUS_MODE_ON, + CONTINUOUS_MODE_MAX, +}; + +enum v4l2_continuous_fps { + MULTI_CAPTURE_FPS_1 = 0, + MULTI_CAPTURE_FPS_10, + MULTI_CAPTURE_FPS_5, + MULTI_CAPTURE_FPS_3, + MULTI_CAPTURE_FPS_MAX, +}; + +enum v4l2_burst_mode { + BURST_MODE_OFF = 0, + BURST_MODE_ON, +}; + +enum v4l2_best_mode { + BEST_MODE_OFF = 0, + BEST_MODE_ON, + BEST_MODE_MAX,}; + +enum v4l2_lowlight_mode { + LOWLIGHT_MODE_OFF = 0, + LOWLIGHT_MODE_ON, + LOWLIGHT_MODE_MAX,}; + +#define V4L2_CID_CAMERA_FD_EYE_BLINK_RESULT (V4L2_CID_PRIVATE_BASE+138) + +#define V4L2_CID_CAMERA_OPTICAL_ZOOM_STEP (V4L2_CID_PRIVATE_BASE + 139) +#define V4L2_CID_CAMERA_OPTICAL_ZOOM_CTRL (V4L2_CID_PRIVATE_BASE + 140) +enum v4l2_optical_zoom_ctrl { + V4L2_OPTICAL_ZOOM_STOP, + V4L2_OPTICAL_ZOOM_TELE_START, + V4L2_OPTICAL_ZOOM_WIDE_START, + V4L2_OPTICAL_ZOOM_SLOW_TELE_START, + V4L2_OPTICAL_ZOOM_SLOW_WIDE_START, +}; + +#define V4L2_CID_CAMERA_LDC (V4L2_CID_PRIVATE_BASE+142) +enum set_LDC_mode { + LDC_SET_OFF = 0, + LDC_SET_ON = 1, +}; + +#define V4L2_CID_CAMERA_LSC (V4L2_CID_PRIVATE_BASE+143) +enum set_LSC_mode { + LSC_SET_OFF = 0, + LSC_SET_ON = 1, +}; + +#define V4L2_CID_CAMERA_FACTORY_OIS (V4L2_CID_PRIVATE_BASE+147) +enum set_Factory_OIS { + FACTORY_OIS_RETURN_TO_CENTER = 0, + FACTORY_OIS_RUN = 1, + FACTORY_OIS_START = 2, + FACTORY_OIS_STOP = 3, + FACTORY_OIS_MODE_ON = 4, + FACTORY_OIS_MODE_OFF = 5, + FACTORY_OIS_LOG = 6, + FACTORY_OIS_ON = 7, +}; + +#define V4L2_CID_CAMERA_FACTORY_ZOOM_RANGE_CHECK_DATA_MIN \ + (V4L2_CID_PRIVATE_BASE+148) +#define V4L2_CID_CAMERA_FACTORY_ZOOM_RANGE_CHECK_DATA_MAX \ + (V4L2_CID_PRIVATE_BASE+149) +#define V4L2_CID_CAMERA_FACTORY_ZOOM_SLOPE_CHECK_DATA_MIN \ + (V4L2_CID_PRIVATE_BASE+152) +#define V4L2_CID_CAMERA_FACTORY_ZOOM_SLOPE_CHECK_DATA_MAX \ + (V4L2_CID_PRIVATE_BASE+153) +#define V4L2_CID_CAMERA_FACTORY_ZOOM_STEP (V4L2_CID_PRIVATE_BASE+154) +#define V4L2_CID_CAMERA_FACTORY_ZOOM (V4L2_CID_PRIVATE_BASE+155) +enum set_Factory_Zoom { + FACTORY_ZOOM_MOVE_STEP = 0, + FACTORY_ZOOM_RANGE_CHECK_START = 1, + FACTORY_ZOOM_RANGE_CHECK_STOP = 2, + FACTORY_ZOOM_SLOPE_CHECK_START = 3, + FACTORY_ZOOM_SLOPE_CHECK_STOP = 4, + FACTORY_ZOOM_SET_RANGE_CHECK_DATA = 5, + FACTORY_ZOOM_SET_SLOPE_CHECK_DATA = 6, + FACTORY_ZOOM_STEP_TELE = 7, + FACTORY_ZOOM_STEP_WIDE = 8, + FACTORY_ZOOM_MOVE_END_CHECK = 9, +}; + +#define V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_MIN \ + (V4L2_CID_PRIVATE_BASE+156) +#define V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_MAX \ + (V4L2_CID_PRIVATE_BASE+157) +#define V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_NUM \ + (V4L2_CID_PRIVATE_BASE+158) +#define V4L2_CID_CAMERA_FACTORY_PUNT (V4L2_CID_PRIVATE_BASE+159) +enum set_Factory_Punt { + FACTORY_PUNT_RANGE_START = 0, + FACTORY_PUNT_RANGE_STOP = 1, + FACTORY_PUNT_SHORT_SCAN_DATA = 2, + FACTORY_PUNT_SHORT_SCAN_START = 3, + FACTORY_PUNT_SHORT_SCAN_STOP = 4, + FACTORY_PUNT_LONG_SCAN_DATA = 5, + FACTORY_PUNT_LONG_SCAN_START = 6, + FACTORY_PUNT_LONG_SCAN_STOP = 7, + FACTORY_PUNT_LOG = 8, + FACTORY_PUNT_SET_RANGE_DATA = 9, + FACTORY_PUNT_EEP_WRITE = 10, +}; + +#define V4L2_CID_CAMERA_FACTORY_FAIL_STOP (V4L2_CID_PRIVATE_BASE+160) +enum set_Factory_Fail_Stop { + FACTORY_FAIL_STOP_ON = 0, + FACTORY_FAIL_STOP_OFF = 1, + FACTORY_FAIL_STOP_RUN = 2, + FACTORY_FAIL_STOP_STOP = 3, +}; + +#define V4L2_CID_CAMERA_FACTORY_NODEFOCUS (V4L2_CID_PRIVATE_BASE+161) +enum set_Factory_NoDeFocus { + FACTORY_NODEFOCUSYES_ON = 0, + FACTORY_NODEFOCUSYES_OFF = 1, + FACTORY_NODEFOCUSYES_RUN = 2, + FACTORY_NODEFOCUSYES_STOP = 3, +}; + +#define V4L2_CID_CAMERA_FACTORY_INTERPOLATION (V4L2_CID_PRIVATE_BASE+162) +enum set_Factory_Interpolation { + FACTORY_INTERPOLATION_USE = 0, + FACTORY_INTERPOLATION_RELEASE = 1, +}; + +#define V4L2_CID_CAMERA_FACTORY_DOWN_RESULT (V4L2_CID_PRIVATE_BASE+163) +#define V4L2_CID_CAMERA_FACTORY_END_RESULT (V4L2_CID_PRIVATE_BASE+164) +#define V4L2_CID_CAMERA_FACTORY_COMMON (V4L2_CID_PRIVATE_BASE+165) +enum set_Factory_Common { + FACTORY_FIRMWARE_DOWNLOAD = 0, + FACTORY_DOWNLOAD_CHECK = 1, + FACTORY_END_CHECK = 2, + FACTORY_COMMON_SET_FOCUS_ZONE_MACRO = 3, + FACTORY_FPS30_ON = 4, + FACTORY_FPS30_OFF = 5, +}; + +#define V4L2_CID_CAMERA_FACTORY_VIB (V4L2_CID_PRIVATE_BASE+166) +enum set_Factory_Vib { + FACTORY_VIB_START = 0, + FACTORY_VIB_STOP = 1, + FACTORY_VIB_LOG = 2, +}; + +#define V4L2_CID_CAMERA_FACTORY_GYRO (V4L2_CID_PRIVATE_BASE+167) +enum set_Factory_Gyro { + FACTORY_GYRO_START = 0, + FACTORY_GYRO_STOP = 1, + FACTORY_GYRO_LOG = 2, +}; + +#define V4L2_CID_CAMERA_FACTORY_BACKLASH (V4L2_CID_PRIVATE_BASE+168) +enum set_Factory_Backlash { + FACTORY_BACKLASH_INPUT = 0, + FACTORY_BACKLASH_MAX_THR = 1, + FACTORY_BACKLASH_WIDE_RUN = 2, + FACTORY_BACKLASH_LOG = 3, +}; + +#define V4L2_CID_CAMERA_FACTORY_AF_STEP_SET (V4L2_CID_PRIVATE_BASE+169) +#define V4L2_CID_CAMERA_FACTORY_AF_POSITION (V4L2_CID_PRIVATE_BASE+170) +#define V4L2_CID_CAMERA_FACTORY_AF_INT_RESULT (V4L2_CID_PRIVATE_BASE+171) +#define V4L2_CID_CAMERA_FACTORY_AF (V4L2_CID_PRIVATE_BASE+172) +enum set_Factory_AF { + FACTORY_AF_LOCK_ON_SET = 0, + FACTORY_AF_LOCK_OFF_SET = 1, + FACTORY_AF_MOVE = 2, + FACTORY_AF_STEP_LOG = 3, + FACTORY_AF_LOCK_START = 4, + FACTORY_AF_LOCK_STOP = 5, + FACTORY_AF_FOCUS_LOG = 6, + FACTORY_AF_INT_SET = 7, + FACTORY_AF_SCAN_LIMIT_START = 8, + FACTORY_AF_SCAN_LIMIT_STOP = 10, + FACTORY_AF_SCAN_RANGE_START = 11, + FACTORY_AF_SCAN_RANGE_STOP = 12, + FACTORY_AF_STEP_SAVE = 13, + FACTORY_AF_LED_END_CHECK = 14, + FACTORY_AF_LED_LOG = 15, + FACTORY_AF_MOVE_END_CHECK = 16, + FACTORY_AF_SCAN_END_CHECK = 17, +}; + +#define V4L2_CID_CAMERA_FACTORY_DEFOCUS_WIDE (V4L2_CID_PRIVATE_BASE+173) +#define V4L2_CID_CAMERA_FACTORY_DEFOCUS_TELE (V4L2_CID_PRIVATE_BASE+174) +#define V4L2_CID_CAMERA_FACTORY_DEFOCUS (V4L2_CID_PRIVATE_BASE+175) +enum set_Factory_DeFocus { + FACTORY_DEFOCUS_RUN = 0, + FACTORY_DEFOCUS_STOP = 1, +}; + +#define V4L2_CID_CAMERA_FACTORY_RESOL_CAP (V4L2_CID_PRIVATE_BASE+176) +enum set_Factory_Resol_Cap { + FACTORY_CAP_COMP_ON = 0, + FACTORY_CAP_COMP_OFF = 1, + FACTORY_CAP_BARREL_ON = 2, + FACTORY_CAP_BARREL_OFF = 3, + FACTORY_CAP_BARREL_START = 4, + FACTORY_CAP_BARREL_STOP = 5, + FACTORY_CAP_COMP_START = 6, + FACTORY_CAP_COMP_STOP = 7, +}; + +#define V4L2_CID_CAMERA_SET_G_VALUE (V4L2_CID_PRIVATE_BASE + 177) +#define V4L2_CID_CAMERA_SET_B_VALUE (V4L2_CID_PRIVATE_BASE + 178) +#define V4L2_CID_CAMERA_SET_A_VALUE (V4L2_CID_PRIVATE_BASE + 179) +#define V4L2_CID_CAMERA_SET_M_VALUE (V4L2_CID_PRIVATE_BASE + 180) +#define V4L2_CID_CAMERA_SET_GBAM (V4L2_CID_PRIVATE_BASE + 181) +#define V4L2_CID_CAMERA_SET_K_VALUE (V4L2_CID_PRIVATE_BASE + 182) +#define V4L2_CID_CAMERA_SET_FLASH_EVC_STEP (V4L2_CID_PRIVATE_BASE + 183) + +#define V4L2_CID_CAMERA_APERTURE_CMD (V4L2_CID_PRIVATE_BASE+184) +enum set_Factory_Aperture_Cmd { + FACTORY_CMD_PREVIEW = 0, + FACTORY_CMD_CAPTURE = 1, +}; + +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_MIN (V4L2_CID_PRIVATE_BASE+185) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_MAX (V4L2_CID_PRIVATE_BASE+186) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_Y_MIN (V4L2_CID_PRIVATE_BASE+187) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_Y_MAX (V4L2_CID_PRIVATE_BASE+188) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_GAIN \ + (V4L2_CID_PRIVATE_BASE+189) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_PEAK_X \ + (V4L2_CID_PRIVATE_BASE+190) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_PEAK_Y \ + (V4L2_CID_PRIVATE_BASE+191) + +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_X_MIN (V4L2_CID_PRIVATE_BASE+192) +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_X_MAX (V4L2_CID_PRIVATE_BASE+193) +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_Y_MIN (V4L2_CID_PRIVATE_BASE+194) +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_Y_MAX (V4L2_CID_PRIVATE_BASE+195) +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_PEAK_X \ + (V4L2_CID_PRIVATE_BASE+196) +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_PEAK_Y \ + (V4L2_CID_PRIVATE_BASE+197) + +#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_X_MIN \ + (V4L2_CID_PRIVATE_BASE+198) +#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_X_MAX \ + (V4L2_CID_PRIVATE_BASE+199) +#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_Y_MIN \ + (V4L2_CID_PRIVATE_BASE+200) +#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_Y_MAX \ + (V4L2_CID_PRIVATE_BASE+202) + +#define V4L2_CID_CAMERA_FACTORY_TEST_NUMBER (V4L2_CID_PRIVATE_BASE+203) + +#define V4L2_CID_CAMERA_FACTORY_BACKLASH_COUNT (V4L2_CID_PRIVATE_BASE+204) +#define V4L2_CID_CAMERA_FACTORY_BACKLASH_MAXTHRESHOLD \ + (V4L2_CID_PRIVATE_BASE+205) + +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_CTRL (V4L2_CID_PRIVATE_BASE + 206) +enum set_Factory_Cap_Ctrl { + FACTORY_STILL_CAP_NORMAL = 0, + FACTORY_STILL_CAP_DUALCAP = 1, + FACTORY_DUAL_CAP_ON = 2, + FACTORY_DUAL_CAP_OFF = 3, +}; + +#define V4L2_CID_CAMERA_DUAL_POSTVIEW (V4L2_CID_PRIVATE_BASE + 207) +#define V4L2_CID_CAMERA_DUAL_CAPTURE (V4L2_CID_PRIVATE_BASE + 208) +#define V4L2_CID_CAMERA_SET_DUAL_CAPTURE (V4L2_CID_PRIVATE_BASE + 209) +#define V4L2_CID_CAMERA_DUAL_CAPTURE_MODE (V4L2_CID_PRIVATE_BASE + 210) + +#define V4L2_CID_CAMERA_FOCUS_AREA_MODE (V4L2_CID_PRIVATE_BASE + 211) +enum set_fouce_area { + V4L2_FOCUS_AREA_CENTER = 0, + V4L2_FOCUS_AREA_MULTI = 1, + V4L2_FOCUS_AREA_SMART_TOUCH = 2, +}; + +#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_LIMIT_MIN (V4L2_CID_PRIVATE_BASE+212) +#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_LIMIT_MAX (V4L2_CID_PRIVATE_BASE+213) +#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_RANGE_MIN (V4L2_CID_PRIVATE_BASE+214) +#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_RANGE_MAX (V4L2_CID_PRIVATE_BASE+215) +#define V4L2_CID_CAM_APERTURE_PREVIEW (V4L2_CID_PRIVATE_BASE+216) +#define V4L2_CID_CAM_APERTURE_CAPTURE (V4L2_CID_PRIVATE_BASE+217) + +#define V4L2_CID_CAMERA_FACTORY_AF_ZONE (V4L2_CID_PRIVATE_BASE+218) +enum set_Factory_AFZone_Cmd { + FACTORY_AFZONE_NORMAL = 0, + FACTORY_AFZONE_MACRO, + FACTORY_AFZONE_AUTO, +}; + +#define V4L2_CID_CAMERA_FACTORY_OIS_SHIFT (V4L2_CID_PRIVATE_BASE+219) +#define V4L2_CID_CAMERA_FACTORY_FLICKER (V4L2_CID_PRIVATE_BASE+220) +enum set_Factory_Flicker_Cmd { + FACTORY_FLICKER_AUTO = 0, + FACTORY_FLICKER_50HZ, + FACTORY_FLICKER_60HZ, + FACTORY_FLICKER_50_60, + FACTORY_FLICKER_OFF, +}; + +#define V4L2_CID_CAMERA_FACTORY_AF_LENS (V4L2_CID_PRIVATE_BASE+221) +enum set_Factory_AFLENS_Cmd { + FACTORY_AFLENS_OPEN = 0, + FACTORY_AFLENS_CLOSE, +}; + +#define V4L2_CID_CAMERA_FACTORY_LV_TARGET (V4L2_CID_PRIVATE_BASE+222) + +#define V4L2_CID_CAMERA_FACTORY_ADJ_IRIS_RANGE_MIN (V4L2_CID_PRIVATE_BASE+223) +#define V4L2_CID_CAMERA_FACTORY_ADJ_IRIS_RANGE_MAX (V4L2_CID_PRIVATE_BASE+224) +#define V4L2_CID_CAMERA_FACTORY_ADJ_IRIS (V4L2_CID_PRIVATE_BASE+225) +enum set_Factory_Adj_IRIS_Cmd { + FACTORY_ADJ_IRIS_RUN = 0, + FACTORY_ADJ_IRIS_STOP, + FACTORY_ADJ_IRIS_END_CHECK, + FACTORY_ADJ_IRIS_LOG, +}; + +#define V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MIN \ + (V4L2_CID_PRIVATE_BASE+226) +#define V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MAX \ + (V4L2_CID_PRIVATE_BASE+227) +#define V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW (V4L2_CID_PRIVATE_BASE+228) +enum set_Factory_Adj_Gain_LiveView_Cmd { + FACTORY_ADJ_GAIN_LIVEVIEW_RUN = 0, + FACTORY_ADJ_GAIN_LIVEVIEW_STOP, + FACTORY_ADJ_GAIN_LIVEVIEW_END_CHECK, + FACTORY_ADJ_GAIN_LIVEVIEW_LOG, +}; + +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_IRIS_NUM (V4L2_CID_PRIVATE_BASE+229) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SET_IRIS (V4L2_CID_PRIVATE_BASE+230) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_ISO (V4L2_CID_PRIVATE_BASE+231) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_RANGE (V4L2_CID_PRIVATE_BASE+232) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SPEEDTIME_X (V4L2_CID_PRIVATE_BASE+233) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SPEEDTIME_Y (V4L2_CID_PRIVATE_BASE+234) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE (V4L2_CID_PRIVATE_BASE+235) +enum set_Factory_SH_Close_Cmd { + FACTORY_SH_CLOSE_RUN = 0, + FACTORY_SH_CLOSE_STOP, + FACTORY_SH_CLOSE_END_CHECK, + FACTORY_SH_CLOSE_LOG, +}; + +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_RANGE_MIN \ + (V4L2_CID_PRIVATE_BASE+236) +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_RANGE_MAX \ + (V4L2_CID_PRIVATE_BASE+237) +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN (V4L2_CID_PRIVATE_BASE+238) +enum set_Factory_Capture_Gain_Cmd { + FACTORY_CAPTURE_GAIN_RUN = 0, + FACTORY_CAPTURE_GAIN_STOP, + FACTORY_CAPTURE_GAIN_END_CHECK, + FACTORY_CAPTURE_GAIN_LOG, +}; + +#define V4L2_CID_CAMERA_FACTORY_LSC_TABLE (V4L2_CID_PRIVATE_BASE+239) +#define V4L2_CID_CAMERA_FACTORY_LSC_REFERENCE (V4L2_CID_PRIVATE_BASE+240) + +#define V4L2_CID_CAMERA_FACTORY_PUNT_SHORT_SCAN_DATA (V4L2_CID_PRIVATE_BASE+241) +#define V4L2_CID_CAMERA_FACTORY_PUNT_LONG_SCAN_DATA (V4L2_CID_PRIVATE_BASE+242) + +#define V4L2_CID_CAMERA_PASM_MODE (V4L2_CID_PRIVATE_BASE + 243) +enum set_camera_mode_Cmd { + MODE_SMART_AUTO = 0, + MODE_PROGRAM, + MODE_A, + MODE_S, + MODE_M, + MODE_VIDEO, + MODE_BACKGROUND_BLUR, + MODE_HIGH_SPEED, + MODE_LIGHT_TRAIL_SHOT, + MODE_WATERFALL, + MODE_SILHOUETTE, + MODE_SUNSET, + MODE_CLOSE_UP, + MODE_FIREWORKS, + MODE_CROSS_FILTER, + MODE_BACKLIGHT, + MODE_BLUE_SKY, + MODE_NATURAL_GREEN, + MODE_BEST_GROUP_POSE, + MODE_FOOD, + MODE_START_FILTER, + MODE_MOVING_SHOT, +}; + +#define V4L2_CID_CAMERA_SHUTTER_SPEED (V4L2_CID_PRIVATE_BASE + 244) +#define V4L2_CID_CAMERA_F_NUMBER (V4L2_CID_PRIVATE_BASE + 245) + +#define V4L2_CID_CAMERA_IMAGE_STABILIZER (V4L2_CID_PRIVATE_BASE + 246) +enum set_Image_Stabilizer { + V4L2_IMAGE_STABILIZER_OFF = 0, + V4L2_IMAGE_STABILIZER_OIS = 1, + V4L2_IMAGE_STABILIZER_DUALIS = 2, +}; + +#define V4L2_CID_CAMERA_IS_OIS_MODE (V4L2_CID_PRIVATE_BASE + 247) +enum set_IS_OIS_mode { + V4L2_IS_OIS_NONE = 0, + V4L2_IS_OIS_MOVIE = 1, + V4L2_IS_OIS_STILL = 2, + V4L2_IS_OIS_MULTI = 3, + V4L2_IS_OIS_VSS = 4, +}; + +#define V4L2_CID_CAMERA_FACTORY_AE_TARGET (V4L2_CID_PRIVATE_BASE + 248) + +#define V4L2_CID_CAMERA_AV (V4L2_CID_PRIVATE_BASE + 249) +#define V4L2_CID_CAMERA_TV (V4L2_CID_PRIVATE_BASE + 250) +#define V4L2_CID_CAMERA_SV (V4L2_CID_PRIVATE_BASE + 251) +#define V4L2_CID_CAMERA_EV (V4L2_CID_PRIVATE_BASE + 252) + +#define V4L2_CID_CAMERA_SCENE_SUB_MODE (V4L2_CID_PRIVATE_BASE + 253) + +#define V4L2_CID_CAMERA_WB_CUSTOM_X (V4L2_CID_PRIVATE_BASE + 254) +#define V4L2_CID_CAMERA_WB_CUSTOM_Y (V4L2_CID_PRIVATE_BASE + 255) +#define V4L2_CID_CAMERA_WB_CUSTOM_VALUE (V4L2_CID_PRIVATE_BASE + 256) + +#define V4L2_CID_CAMERA_RED_EYE_FIX_RESULT (V4L2_CID_PRIVATE_BASE + 257) +#define V4L2_CID_CAMERA_FACTORY_FLASH (V4L2_CID_PRIVATE_BASE + 258) +enum set_Factory_Flash_Cmd { + FACTORY_FLASH_STROBE_CHECK_ON = 0, + FACTORY_FLASH_STROBE_CHECK_OFF = 1, + FACTORY_FLASH_CHARGE = 2, + FACTORY_FLASH_LOG = 3, + FACTORY_FLASH_CHARGE_END_CHECK = 4, + FACTORY_FLASH_STROBE_CHARGE_END_CHECK = 5, + FACTORY_FLASH_WB_LOG = 6, + FACTORY_ADJ_FLASH_WB_LOG = 7, + FACTORY_ADJ_FLASH_WB_END_CHECK = 8, +}; + +#define V4L2_CID_CAMERA_FACTORY_WB (V4L2_CID_PRIVATE_BASE + 259) +enum set_Factory_WB_Cmd { + FACTORY_WB_INDOOR_RUN = 0, + FACTORY_WB_INDOOR_END_CHECK = 1, + FACTORY_WB_OUTDOOR_RUN = 2, + FACTORY_WB_OUTDOOR_END_CHECK = 3, + FACTORY_WB_LOG = 4, +}; + +#define V4L2_CID_CAMERA_FACTORY_FLASH_RANGE_X (V4L2_CID_PRIVATE_BASE + 260) +#define V4L2_CID_CAMERA_FACTORY_FLASH_RANGE_Y (V4L2_CID_PRIVATE_BASE + 261) + +#define V4L2_CID_CAMERA_FACTORY_WB_IN_RG_VALUE (V4L2_CID_PRIVATE_BASE + 262) +#define V4L2_CID_CAMERA_FACTORY_WB_IN_BG_VALUE (V4L2_CID_PRIVATE_BASE + 263) +#define V4L2_CID_CAMERA_FACTORY_WB_OUT_RG_VALUE (V4L2_CID_PRIVATE_BASE + 264) +#define V4L2_CID_CAMERA_FACTORY_WB_OUT_BG_VALUE (V4L2_CID_PRIVATE_BASE + 265) + +#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_START_X \ + (V4L2_CID_PRIVATE_BASE + 266) +#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_END_X \ + (V4L2_CID_PRIVATE_BASE + 267) +#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_START_Y \ + (V4L2_CID_PRIVATE_BASE + 268) +#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_END_Y \ + (V4L2_CID_PRIVATE_BASE + 269) + +#define V4L2_CID_CAMERA_FACTORY_AF_LED_TIME (V4L2_CID_PRIVATE_BASE + 270) + +#define V4L2_CID_CAMERA_FACTORY_AF_DIFF_CHECK_MIN (V4L2_CID_PRIVATE_BASE + 271) +#define V4L2_CID_CAMERA_FACTORY_AF_DIFF_CHECK_MAX (V4L2_CID_PRIVATE_BASE + 272) + +#define V4L2_CID_CAMERA_FACTORY_DEFECTPIXEL (V4L2_CID_PRIVATE_BASE + 273) +enum set_Factory_DefectPixel_Cmd { + FACTORY_DEFECTPIXEL_SCENARIO_6 = 0, + FACTORY_DEFECTPIXEL_RUN, + FACTORY_DEFECTPIXEL_END_CHECK, + FACTORY_DEFECTPIXEL_LOG, + FACTORY_DEFECTPIXEL_CID_1, + FACTORY_DEFECTPIXEL_CID_2, + FACTORY_DEFECTPIXEL_CID_3, + FACTORY_DEFECTPIXEL_WRITE_BLACK, + FACTORY_DEFECTPIXEL_WRITE_WHITE, + FACTORY_DEFECTPIXEL_CID_WRITE, + FACTORY_DEFECTPIXEL_FLASH_MERGE, + FACTORY_DEFECTPIXEL_DOT_WRITE_CHECK, +}; + +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_CAP (V4L2_CID_PRIVATE_BASE + 274) +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR0 (V4L2_CID_PRIVATE_BASE + 275) +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR1 (V4L2_CID_PRIVATE_BASE + 276) +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR2 (V4L2_CID_PRIVATE_BASE + 277) +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR_HS (V4L2_CID_PRIVATE_BASE + 278) + +#define V4L2_CID_CAMERA_FACTORY_AF_LED_LV_MIN (V4L2_CID_PRIVATE_BASE + 279) +#define V4L2_CID_CAMERA_FACTORY_AF_LED_LV_MAX (V4L2_CID_PRIVATE_BASE + 280) + +#define V4L2_CID_CAMERA_FACTORY_CAM_SYS_MODE (V4L2_CID_PRIVATE_BASE + 281) +enum set_Factory_Sysmode_Cmd { + FACTORY_SYSMODE_CAPTURE = 0, + FACTORY_SYSMODE_MONITOR = 1, + FACTORY_SYSMODE_PARAM = 2, +}; + +#define V4L2_CID_CAMERA_FACTORY_ISP_FW_CHECK (V4L2_CID_PRIVATE_BASE + 282) +#define V4L2_CID_CAMERA_FACTORY_OIS_VER_CHECK (V4L2_CID_PRIVATE_BASE + 283) + +#define V4L2_CID_CAMERA_SMART_SCENE_DETECT (V4L2_CID_PRIVATE_BASE+284) +enum set_smartscenedetect_mode { + SMART_SCENE_DETECT_OFF = 0, + SMART_SCENE_DETECT_ON = 1, +}; +#define V4L2_CID_CAMERA_SMART_MOVIE_RECORDING (V4L2_CID_PRIVATE_BASE+285) +#define V4L2_CID_CAMERA_SMART_AUTO_S1_PUSH (V4L2_CID_PRIVATE_BASE+286) + +#define V4L2_CID_CAMERA_FACTORY_WB_RANGE_FLASH_WRITE \ + (V4L2_CID_PRIVATE_BASE + 287) + +#define V4L2_CID_CAMERA_FACTORY_FLASH_CHR_CHK_TM \ + (V4L2_CID_PRIVATE_BASE + 288) + +#define V4L2_CID_CAMERA_EXIF_AV (V4L2_CID_PRIVATE_BASE + 289) +#define V4L2_CID_CAMERA_FACE_DETECT_NUMBER (V4L2_CID_PRIVATE_BASE+290) +#define V4L2_CID_CAMERA_EXIF_FL (V4L2_CID_PRIVATE_BASE + 291) + +#define V4L2_CID_CAMERA_SMART_ZOOM (V4L2_CID_PRIVATE_BASE + 292) +enum set_Smart_Zoom { + V4L2_SMART_ZOOM_OFF = 0, + V4L2_SMART_ZOOM_ON = 1, +}; + +#define V4L2_CID_CAMERA_CAF (V4L2_CID_PRIVATE_BASE + 293) + +#define V4L2_CID_CAMERA_FACTORY_LIVEVIEW_OFFSET_MARK \ + (V4L2_CID_PRIVATE_BASE + 294) +#define V4L2_CID_CAMERA_FACTORY_LIVEVIEW_OFFSET_VAL \ + (V4L2_CID_PRIVATE_BASE + 295) + +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_OFFSET_MARK \ + (V4L2_CID_PRIVATE_BASE + 296) +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_OFFSET_VAL \ + (V4L2_CID_PRIVATE_BASE + 297) + +#define V4L2_CID_CAMERA_FACTORY_WB_RANGE (V4L2_CID_PRIVATE_BASE + 298) + +#define V4L2_CID_CAMERA_LV (V4L2_CID_PRIVATE_BASE + 299) + +#define V4L2_CID_PHYSICAL_ROTATION (V4L2_CID_PRIVATE_BASE + 300) + +#define V4L2_CID_CAMERA_FOCUS_RANGE (V4L2_CID_PRIVATE_BASE + 301) +enum set_fouce_range { + V4L2_FOCUS_RANGE_AUTO = 0, + V4L2_FOCUS_RANGE_MACRO = 1, + V4L2_FOCUS_RANGE_AUTO_MACRO = 2, +}; + +#define V4L2_CID_CAMERA_TIME_INFO (V4L2_CID_PRIVATE_BASE + 302) + +#define V4L2_CID_CAMERA_AF_LED (V4L2_CID_PRIVATE_BASE + 303) +enum set_AF_LED { + V4L2_AF_LED_OFF = 0, + V4L2_AF_LED_ON = 1, +}; + +#define V4L2_CID_CAMERA_LENS_TIMER (V4L2_CID_PRIVATE_BASE + 304) + +#define V4L2_CID_CAMERA_FLASH_BATT_INFO (V4L2_CID_PRIVATE_BASE + 305) +enum set_FLASH_BATT_INFO { + V4L2_FLASH_NORMAL_BATT = 0, + V4L2_FLASH_LOW_BATT = 1, +}; + +#define V4L2_CID_CAMERA_STREAM_PART2 (V4L2_CID_PRIVATE_BASE + 306) + +#define V4L2_CID_CAMERA_WIDGET_MODE_LEVEL (V4L2_CID_PRIVATE_BASE+307) +enum v4l2_widget_mode_level { + V4L2_WIDGET_MODE_LEVEL_1 = 1, + V4L2_WIDGET_MODE_LEVEL_2 = 2, + V4L2_WIDGET_MODE_LEVEL_3 = 3, +}; + +#define V4L2_CID_CAMERA_SMART_READ1 (V4L2_CID_PRIVATE_BASE + 308) +#define V4L2_CID_CAMERA_SMART_READ2 (V4L2_CID_PRIVATE_BASE + 309) + +#define V4L2_CID_CAMERA_PREVIEW_WIDTH (V4L2_CID_PRIVATE_BASE + 310) +#define V4L2_CID_CAMERA_PREVIEW_HEIGHT (V4L2_CID_PRIVATE_BASE + 311) +#define V4L2_CID_CAMERA_PREVIEW_SIZE (V4L2_CID_PRIVATE_BASE + 312) + +#define V4L2_CID_CAMERA_WARNING_CONDITION (V4L2_CID_PRIVATE_BASE + 313) +#define V4L2_CID_CAMERA_EXIF_FL_35mm (V4L2_CID_PRIVATE_BASE + 314) + +#define V4L2_CID_CAMERA_LENS_STATUS (V4L2_CID_PRIVATE_BASE + 315) +#define V4L2_CID_CAMERA_HOLD_LENS (V4L2_CID_PRIVATE_BASE + 316) + +/* Pixel format FOURCC depth Description */ +enum v4l2_pix_format_mode { + V4L2_PIX_FMT_MODE_PREVIEW, + V4L2_PIX_FMT_MODE_CAPTURE, + V4L2_PIX_FMT_MODE_HDR, + V4L2_PIX_FMT_MODE_VT_MIRROR, + V4L2_PIX_FMT_MODE_VT_NONMIRROR, +}; + +#define V4L2_CID_SET_CONTINUE_FPS (V4L2_CID_PRIVATE_BASE + 500) +#define V4L2_CID_CONTINUESHOT_PROC (V4L2_CID_PRIVATE_BASE + 501) +enum v4l2_continuecshot_proc_state { + V4L2_INT_STATE_FRAME_SYNC = 0, + V4L2_INT_STATE_CAPTURE_SYNC, + V4L2_INT_STATE_CONTINUE_CANCEL, + V4L2_INT_STATE_CONTINUE_END, + V4L2_INT_STATE_START_CAPTURE, +}; + +#define V4L2_CID_CAMERA_GET_MODE (V4L2_CID_PRIVATE_BASE + 502) + +#define V4L2_CID_CAMERA_FACTORY_SEND_SETTING \ + (V4L2_CID_PRIVATE_BASE + 503) +#define V4L2_CID_CAMERA_FACTORY_SEND_VALUE \ + (V4L2_CID_PRIVATE_BASE + 504) + +#define V4L2_CID_CAMERA_FACTORY_TILT_SCAN_MIN \ + (V4L2_CID_PRIVATE_BASE + 505) +#define V4L2_CID_CAMERA_FACTORY_TILT_SCAN_MAX \ + (V4L2_CID_PRIVATE_BASE + 506) +#define V4L2_CID_CAMERA_FACTORY_TILT_FIELD \ + (V4L2_CID_PRIVATE_BASE + 507) +#define V4L2_CID_CAMERA_FACTORY_TILT_AF_RANGE_MIN \ + (V4L2_CID_PRIVATE_BASE + 508) +#define V4L2_CID_CAMERA_FACTORY_TILT_AF_RANGE_MAX \ + (V4L2_CID_PRIVATE_BASE + 509) +#define V4L2_CID_CAMERA_FACTORY_TILT_DIFF_RANGE_MIN \ + (V4L2_CID_PRIVATE_BASE + 510) +#define V4L2_CID_CAMERA_FACTORY_TILT_DIFF_RANGE_MAX \ + (V4L2_CID_PRIVATE_BASE + 511) + +#define V4L2_CID_CAMERA_FACTORY_IR_R_GAIN_MIN \ + (V4L2_CID_PRIVATE_BASE + 512) +#define V4L2_CID_CAMERA_FACTORY_IR_R_GAIN_MAX \ + (V4L2_CID_PRIVATE_BASE + 513) +#define V4L2_CID_CAMERA_FACTORY_IR_B_GAIN_MIN \ + (V4L2_CID_PRIVATE_BASE + 514) +#define V4L2_CID_CAMERA_FACTORY_IR_B_GAIN_MAX \ + (V4L2_CID_PRIVATE_BASE + 515) + +#define V4L2_CID_CAMERA_FACTORY_FLASH_MAN_CHARGE \ + (V4L2_CID_PRIVATE_BASE + 516) +#define V4L2_CID_CAMERA_FACTORY_FLASH_MAN_EN \ + (V4L2_CID_PRIVATE_BASE + 517) + +#define V4L2_CID_CAMERA_FACTORY_SEND_WORD_VALUE \ + (V4L2_CID_PRIVATE_BASE + 518) +#define V4L2_CID_CAMERA_FACTORY_SEND_LONG_VALUE \ + (V4L2_CID_PRIVATE_BASE + 519) + +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR1_HD \ + (V4L2_CID_PRIVATE_BASE + 520) + +#define V4L2_CID_BURSTSHOT_PROC (V4L2_CID_PRIVATE_BASE + 521) +enum v4l2_burst_proc_state { + V4L2_INT_STATE_BURST_START = 0, + V4L2_INT_STATE_BURST_SYNC, + V4L2_INT_STATE_BURST_STOP, +}; + +#define V4L2_CID_CAMERA_FACTORY_TILT \ + (V4L2_CID_PRIVATE_BASE + 522) +enum set_Factory_Tilt { + FACTORY_TILT_ONE_SCRIPT_RUN = 0, + FACTORY_TILT_ONE_SCRIPT_DISP1, + FACTORY_TILT_ONE_SCRIPT_DISP2, + FACTORY_TILT_ONE_SCRIPT_DISP3, + FACTORY_TILT_ONE_SCRIPT_DISP4, + FACTORY_TILT_ONE_SCRIPT_DISP5, +}; + +#define V4L2_CID_CAMERA_FACTORY_IR_CHECK \ + (V4L2_CID_PRIVATE_BASE + 523) +enum set_Factory_IR_Check { + FACTORY_IR_CHECK_LOG = 0, +}; + +#define V4L2_CID_BURSTSHOT_SET_POSTVIEW_SIZE (V4L2_CID_PRIVATE_BASE + 524) + +#define V4L2_CID_BURSTSHOT_SET_SNAPSHOT_SIZE (V4L2_CID_PRIVATE_BASE + 525) + +/* ISP DEBUG CODE */ +#define V4L2_CID_ISP_DEBUG_READ (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 1) +#define V4L2_CID_ISP_DEBUG_WRITE (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 2) +#define V4L2_CID_ISP_DEBUG_READ_MEM (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 3) +#define V4L2_CID_ISP_DEBUG_WRITE_MEM (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 4) +#define V4L2_CID_ISP_DEBUG_READ_FILE (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 5) +#define V4L2_CID_ISP_DEBUG_WRITE_FILE (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 6) +#define V4L2_CID_ISP_DEBUG_LOGV (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 7) + +/* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') +#define V4L2_PIX_FMT_NV21T v4l2_fourcc('T', 'V', '2', '1') +#define V4L2_PIX_FMT_INTERLEAVED v4l2_fourcc('I', 'T', 'L', 'V') + +/* + * * V4L2 extention for digital camera + * */ +/* Strobe flash light */ +enum v4l2_strobe_control { + /* turn off the flash light */ + V4L2_STROBE_CONTROL_OFF = 0, + /* turn on the flash light */ + V4L2_STROBE_CONTROL_ON = 1, + /* act guide light before splash */ + V4L2_STROBE_CONTROL_AFGUIDE = 2, + /* charge the flash light */ + V4L2_STROBE_CONTROL_CHARGE = 3, +}; + +enum v4l2_strobe_conf { + V4L2_STROBE_OFF = 0, /* Always off */ + V4L2_STROBE_ON = 1, /* Always splashes */ + /* Auto control presets */ + V4L2_STROBE_AUTO = 2, + V4L2_STROBE_REDEYE_REDUCTION = 3, + V4L2_STROBE_SLOW_SYNC = 4, + V4L2_STROBE_FRONT_CURTAIN = 5, + V4L2_STROBE_REAR_CURTAIN = 6, + /* Extra manual control presets */ + /* keep turned on until turning off */ + V4L2_STROBE_PERMANENT = 7, + V4L2_STROBE_EXTERNAL = 8, +}; + +enum v4l2_strobe_status { + V4L2_STROBE_STATUS_OFF = 0, + /* while processing configurations */ + V4L2_STROBE_STATUS_BUSY = 1, + V4L2_STROBE_STATUS_ERR = 2, + V4L2_STROBE_STATUS_CHARGING = 3, + V4L2_STROBE_STATUS_CHARGED = 4, +}; + +/* capabilities field */ +/* No strobe supported */ +#define V4L2_STROBE_CAP_NONE 0x0000 +/* Always flash off mode */ +#define V4L2_STROBE_CAP_OFF 0x0001 +/* Always use flash light mode */ +#define V4L2_STROBE_CAP_ON 0x0002 +/* Flashlight works automatic */ +#define V4L2_STROBE_CAP_AUTO 0x0004 +/* Red-eye reduction */ +#define V4L2_STROBE_CAP_REDEYE 0x0008 +/* Slow sync */ +#define V4L2_STROBE_CAP_SLOWSYNC 0x0010 +/* Front curtain */ +#define V4L2_STROBE_CAP_FRONT_CURTAIN 0x0020 +/* Rear curtain */ +#define V4L2_STROBE_CAP_REAR_CURTAIN 0x0040 +/* keep turned on until turning off */ +#define V4L2_STROBE_CAP_PERMANENT 0x0080 +/* use external strobe */ +#define V4L2_STROBE_CAP_EXTERNAL 0x0100 + +/* Set mode and Get status */ +struct v4l2_strobe { + /* off/on/charge:0/1/2 */ + enum v4l2_strobe_control control; + /* supported strobe capabilities */ + __u32 capabilities; + enum v4l2_strobe_conf mode; + enum v4l2_strobe_status status; /* read only */ +/* default is 0 and range of value varies from each models */ + __u32 flash_ev; + __u32 reserved[4]; +}; + +#define VIDIOC_S_STROBE _IOWR('V', 83, struct v4l2_strobe) +#define VIDIOC_G_STROBE _IOR('V', 84, struct v4l2_strobe) + +/* Object recognition and collateral actions */ +enum v4l2_recog_mode { + V4L2_RECOGNITION_MODE_OFF = 0, + V4L2_RECOGNITION_MODE_ON = 1, + V4L2_RECOGNITION_MODE_LOCK = 2, +}; + +enum v4l2_recog_action { + V4L2_RECOGNITION_ACTION_NONE = 0, /* only recognition */ + V4L2_RECOGNITION_ACTION_BLINK = 1, /* Capture on blinking */ + V4L2_RECOGNITION_ACTION_SMILE = 2, /* Capture on smiling */ +}; + +enum v4l2_recog_pattern { + V4L2_RECOG_PATTERN_FACE = 0, /* Face */ + V4L2_RECOG_PATTERN_HUMAN = 1, /* Human */ + V4L2_RECOG_PATTERN_CHAR = 2, /* Character */ +}; + +struct v4l2_recog_rect { + enum v4l2_recog_pattern p; /* detected pattern */ + struct v4l2_rect o; /* detected area */ + __u32 reserved[4]; +}; + +struct v4l2_recog_data { + __u8 detect_cnt; /* detected object counter */ + struct v4l2_rect o; /* detected area */ + __u32 reserved[4]; +}; + +struct v4l2_recognition { + enum v4l2_recog_mode mode; + + /* Which pattern to detect */ + enum v4l2_recog_pattern pattern; + + /* How many object to detect */ + __u8 obj_num; + + /* select detected object */ + __u32 detect_idx; + + /* read only :Get object coordination */ + struct v4l2_recog_data data; + + enum v4l2_recog_action action; + __u32 reserved[4]; +}; + +#define VIDIOC_S_RECOGNITION _IOWR('V', 85, struct v4l2_recognition) +#define VIDIOC_G_RECOGNITION _IOR('V', 86, struct v4l2_recognition) + +#endif /* __LINUX_VIDEODEV2_SAMSUNG_H */ diff --git a/camera/include/linux/videodev2_exynos_media.h b/camera/include/linux/videodev2_exynos_media.h new file mode 100644 index 0000000..2768201 --- /dev/null +++ b/camera/include/linux/videodev2_exynos_media.h @@ -0,0 +1,225 @@ +/* + * Video for Linux Two header file for Exynos + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This header file contains several v4l2 APIs to be proposed to v4l2 + * community and until being accepted, will be used restrictly for Exynos. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_VIDEODEV2_EXYNOS_H +#define __LINUX_VIDEODEV2_EXYNOS_H + +/* Pixel format FOURCC depth Description */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_YUV444_2P v4l2_fourcc('Y', 'U', '2', 'P') /* 24 Y/CbCr */ +#define V4L2_PIX_FMT_YVU444_2P v4l2_fourcc('Y', 'V', '2', 'P') /* 24 Y/CrCb */ + +/* three planes -- one Y, one Cr, one Cb */ +#define V4L2_PIX_FMT_YUV444_3P v4l2_fourcc('Y', 'U', '3', 'P') /* 24 Y/Cb/Cr */ + +/* two non contiguous planes - one Y, one Cr + Cb interleaved */ +/* 21 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') +/* 12 Y/CbCr 4:2:0 16x16 macroblocks */ +#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') + +/* three non contiguous planes - Y, Cb, Cr */ +/* 12 YVU420 planar */ +#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'V', 'U', 'M') + +/* compressed formats */ +#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */ +#define V4L2_PIX_FMT_FIMV v4l2_fourcc('F', 'I', 'M', 'V') /* FIMV */ +#define V4L2_PIX_FMT_FIMV1 v4l2_fourcc('F', 'I', 'M', '1') /* FIMV1 */ +#define V4L2_PIX_FMT_FIMV2 v4l2_fourcc('F', 'I', 'M', '2') /* FIMV2 */ +#define V4L2_PIX_FMT_FIMV3 v4l2_fourcc('F', 'I', 'M', '3') /* FIMV3 */ +#define V4L2_PIX_FMT_FIMV4 v4l2_fourcc('F', 'I', 'M', '4') /* FIMV4 */ +#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ + +/* yuv444 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_444 v4l2_fourcc('J', 'P', 'G', '4') +/* yuv422 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_422 v4l2_fourcc('J', 'P', 'G', '2') +/* yuv420 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_420 v4l2_fourcc('J', 'P', 'G', '0') +/* grey of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_GRAY v4l2_fourcc('J', 'P', 'G', 'G') + +/* + * C O N T R O L S + */ +/* CID base for Exynos controls (USER_CLASS) */ +#define V4L2_CID_EXYNOS_BASE (V4L2_CTRL_CLASS_USER | 0x2000) + +/* for rgb alpha function */ +#define V4L2_CID_GLOBAL_ALPHA (V4L2_CID_EXYNOS_BASE + 1) + +/* cacheable configuration */ +#define V4L2_CID_CACHEABLE (V4L2_CID_EXYNOS_BASE + 10) + +/* jpeg captured size */ +#define V4L2_CID_CAM_JPEG_MEMSIZE (V4L2_CID_EXYNOS_BASE + 20) +#define V4L2_CID_CAM_JPEG_ENCODEDSIZE (V4L2_CID_EXYNOS_BASE + 21) + +#define V4L2_CID_SET_SHAREABLE (V4L2_CID_EXYNOS_BASE + 40) + +/* TV configuration */ +#define V4L2_CID_TV_LAYER_BLEND_ENABLE (V4L2_CID_EXYNOS_BASE + 50) +#define V4L2_CID_TV_LAYER_BLEND_ALPHA (V4L2_CID_EXYNOS_BASE + 51) +#define V4L2_CID_TV_PIXEL_BLEND_ENABLE (V4L2_CID_EXYNOS_BASE + 52) +#define V4L2_CID_TV_CHROMA_ENABLE (V4L2_CID_EXYNOS_BASE + 53) +#define V4L2_CID_TV_CHROMA_VALUE (V4L2_CID_EXYNOS_BASE + 54) +#define V4L2_CID_TV_HPD_STATUS (V4L2_CID_EXYNOS_BASE + 55) +#define V4L2_CID_TV_LAYER_PRIO (V4L2_CID_EXYNOS_BASE + 56) +#define V4L2_CID_TV_SET_DVI_MODE (V4L2_CID_EXYNOS_BASE + 57) + +/* for color space conversion equation selection */ +#define V4L2_CID_CSC_EQ_MODE (V4L2_CID_EXYNOS_BASE + 100) +#define V4L2_CID_CSC_EQ (V4L2_CID_EXYNOS_BASE + 101) +#define V4L2_CID_CSC_RANGE (V4L2_CID_EXYNOS_BASE + 102) + +/* for DRM playback scenario */ +#define V4L2_CID_USE_SYSMMU (V4L2_CID_EXYNOS_BASE + 200) +#define V4L2_CID_M2M_CTX_NUM (V4L2_CID_EXYNOS_BASE + 201) + +/* CID base for MFC controls (MPEG_CLASS) */ +#define V4L2_CID_MPEG_MFC_BASE (V4L2_CTRL_CLASS_MPEG | 0x2000) + +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL \ + (V4L2_CID_MPEG_MFC_BASE + 1) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID \ + (V4L2_CID_MPEG_MFC_BASE + 2) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO \ + (V4L2_CID_MPEG_MFC_BASE + 3) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS \ + (V4L2_CID_MPEG_MFC_BASE + 4) + +#define V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB \ + (V4L2_CID_MPEG_MFC_BASE + 5) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG \ + (V4L2_CID_MPEG_MFC_BASE + 6) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_ENABLE \ + (V4L2_CID_MPEG_MFC_BASE + 7) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA \ + (V4L2_CID_MPEG_MFC_BASE + 8) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA \ + (V4L2_CID_MPEG_MFC_BASE + 9) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA_BOT \ + (V4L2_CID_MPEG_MFC_BASE + 10) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA_BOT \ + (V4L2_CID_MPEG_MFC_BASE + 11) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_GENERATED \ + (V4L2_CID_MPEG_MFC_BASE + 12) +#define V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE \ + (V4L2_CID_MPEG_MFC_BASE + 13) +#define V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS \ + (V4L2_CID_MPEG_MFC_BASE + 14) + +#define V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR \ + (V4L2_CID_MPEG_MFC_BASE + 15) +#define V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR \ + (V4L2_CID_MPEG_MFC_BASE + 16) + +#define V4L2_CID_MPEG_MFC51_VIDEO_STREAM_SIZE \ + (V4L2_CID_MPEG_MFC_BASE + 17) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_COUNT \ + (V4L2_CID_MPEG_MFC_BASE + 18) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TYPE \ + (V4L2_CID_MPEG_MFC_BASE + 19) +enum v4l2_mpeg_mfc51_video_frame_type { + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_NOT_CODED = 0, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_I_FRAME = 1, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_P_FRAME = 2, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_B_FRAME = 3, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_SKIPPED = 4, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_OTHERS = 5, +}; + +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE \ + (V4L2_CID_MPEG_MFC_BASE + 20) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE \ + (V4L2_CID_MPEG_MFC_BASE + 21) +#define V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES \ + (V4L2_CID_MPEG_MFC_BASE + 22) +#define V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA \ + (V4L2_CID_MPEG_MFC_BASE + 23) +#define V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE \ + (V4L2_CID_MPEG_MFC_BASE + 24) + +#define V4L2_CID_MPEG_MFC6X_VIDEO_FRAME_DELTA \ + (V4L2_CID_MPEG_MFC_BASE + 25) + +#define V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH V4L2_CID_MPEG_VIDEO_GOP_SIZE +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH \ + V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE +#define V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH V4L2_CID_MPEG_VIDEO_BITRATE + +/* proposed CIDs, based on 3.3-rc3 */ +#define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_MFC_BASE + 26) + +#define V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_S_B \ + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY + +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING \ + (V4L2_CID_MPEG_MFC_BASE + 27) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 \ + (V4L2_CID_MPEG_MFC_BASE + 28) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE \ + (V4L2_CID_MPEG_MFC_BASE + 29) +enum v4l2_mpeg_video_h264_sei_fp_arrangement_type { + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_CHEKERBOARD = 0, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_COLUMN = 1, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_ROW = 2, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE = 3, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_TOP_BOTTOM = 4, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_TEMPORAL = 5, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO (V4L2_CID_MPEG_MFC_BASE + 30) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE (V4L2_CID_MPEG_MFC_BASE + 31) +enum v4l2_mpeg_video_h264_fmo_map_type { + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES = 0, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES = 1, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER = 2, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT = 3, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN = 4, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN = 5, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT = 6, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP \ + (V4L2_CID_MPEG_MFC_BASE + 32) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION \ + (V4L2_CID_MPEG_MFC_BASE + 33) +enum v4l2_mpeg_video_h264_fmo_change_dir { + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT = 0, + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE \ + (V4L2_CID_MPEG_MFC_BASE + 34) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH \ + (V4L2_CID_MPEG_MFC_BASE + 35) +#define V4L2_CID_MPEG_VIDEO_H264_ASO \ + (V4L2_CID_MPEG_MFC_BASE + 36) +#define V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER \ + (V4L2_CID_MPEG_MFC_BASE + 37) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING \ + (V4L2_CID_MPEG_MFC_BASE + 38) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE \ + (V4L2_CID_MPEG_MFC_BASE + 39) +enum v4l2_mpeg_video_h264_hierarchical_coding_type { + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B = 0, + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER \ + (V4L2_CID_MPEG_MFC_BASE + 40) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP \ + (V4L2_CID_MPEG_MFC_BASE + 41) +#define V4L2_CID_MPEG_VIDEO_H264_MVC_VIEW_ID \ + (V4L2_CID_MPEG_MFC_BASE + 42) +#endif /* __LINUX_VIDEODEV2_EXYNOS_H */ diff --git a/cm.dependencies b/cm.dependencies new file mode 100644 index 0000000..a78a94f --- /dev/null +++ b/cm.dependencies @@ -0,0 +1,18 @@ +[ + { + "repository": "android_device_samsung_smdk4412-common", + "target_path": "device/samsung/smdk4412-common" + }, + { + "repository": "android_kernel_samsung_smdk4412", + "target_path": "kernel/samsung/smdk4412" + }, + { + "repository": "android_packages_apps_SamsungServiceMode", + "target_path": "packages/apps/SamsungServiceMode" + }, + { + "repository": "android_hardware_samsung", + "target_path": "hardware/samsung" + } +] diff --git a/cm.mk b/cm.mk new file mode 100644 index 0000000..bebf11b --- /dev/null +++ b/cm.mk @@ -0,0 +1,21 @@ +# Specify phone tech before including full_phone +$(call inherit-product, vendor/cm/config/gsm.mk) + +# Release name +PRODUCT_RELEASE_NAME := n5100 + +# Inherit some common CM stuff. +$(call inherit-product, vendor/cm/config/common_full_phone.mk) + +# Inherit device configuration +$(call inherit-product, device/samsung/n5100/full_n5100.mk) + +# Device identifier. This must come after all inclusions +PRODUCT_DEVICE := n5100 +PRODUCT_NAME := cm_n5100 +PRODUCT_BRAND := samsung +PRODUCT_MODEL := GT-N5100 +PRODUCT_MANUFACTURER := samsung + +# Set build fingerprint / ID / Product Name ect. +PRODUCT_BUILD_PROP_OVERRIDES += PRODUCT_NAME=GT-N5100 TARGET_DEVICE=GT-N5100 BUILD_FINGERPRINT="samsung/kona3gxx/kona3g:4.3/JSS15J/N5100XXBMD1:user/release-keys" PRIVATE_BUILD_DESC="kona3gxx-user 4.3 JSS15J N5100XXBMD1 release-keys" diff --git a/configs/Android.mk b/configs/Android.mk new file mode 100644 index 0000000..c0d0384 --- /dev/null +++ b/configs/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := tiny_hw +LOCAL_MODULE_OWNER := samsung +LOCAL_SRC_FILES := tiny_hw.xml +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_SUFFIX := .xml +LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/sound +include $(BUILD_PREBUILT) + diff --git a/configs/gps.xml b/configs/gps.xml new file mode 100755 index 0000000..38f16ad --- /dev/null +++ b/configs/gps.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + diff --git a/configs/nvram_mfg.txt b/configs/nvram_mfg.txt new file mode 100755 index 0000000..efb5cad --- /dev/null +++ b/configs/nvram_mfg.txt @@ -0,0 +1,146 @@ +# Kona Rev0.1 2012.10.29-TSSI + +manfid=0x2d0 +prodid=0x05de +vendid=0x14e4 +devid=0x4380 +boardtype=0x05de +boardrev=0x1205 +boardnum=22 +macaddr=00:90:4c:c5:12:38 +sromrev=3 +#boardflags: 5GHz FEM: has ext 5GHz PA + LNA +# 2.4GHz FEM: has ext 2.4GHz PA + SP3T +# 2.4GHz FEM: SP3T switch share with BT +# keep original 0x200 +boardflags=0x10081a01 +xtalfreq=37400 +nocrc=1 +ag0=0 +aa2g=1 +ccode=ALL +pa0itssit=0x20 +#PA parameters for 2.4GHz-10/29 R01 TSSI +pa0b0=0x141E +pa0b1=0xFD89 +pa0b2=0xFF57 + +tssifloor2g=30 +extpagain2g=2 +extpagain5g=2 + +# rssi params for 2.4GHz +rssismf2g=0xf +rssismc2g=0x8 +rssisav2g=0x1 +# rssi params(RFMD) for 2.4GHz +#rssismf2g=0x3 +#rssismc2g=0xa +#rssisav2g=0x1 + +cckPwrOffset=3 +cckdigfilttype=24 +#PwrOffset40mhz2g=-10 +# rssi params for 5GHz +rssismf5g=0xf +rssismc5g=0x7 +rssisav5g=0x1 +#PA parameters for lower a-band-10/29 R01 TSSI +pa1lob0=0x1A12 +pa1lob1=0xFCE0 +pa1lob2=0xFF53 +tssifloor5gl=30 +#PA parameters for midband-10/29 R01 TSSI +pa1b0=0x1B2F +pa1b1=0xFCBB +pa1b2=0xFF4E +tssifloor5gm=30 +#PA paramasdeters for high band-10/29 R01 TSSI +pa1hib0=0x1BDC +pa1hib1=0xFCA3 +pa1hib2=0xFF4B +tssifloor5gh=30 +rxpo5g=0 +maxp2ga0=72 +# 2GTxPwr Backoff +ofdm2gpo=0x66666666 +mcs2gpo0=0x8888 +mcs2gpo1=0x8888 +maxp5ga0=62 +maxp5gla0=58 +maxp5gha0=54 +# 5GTxPwr Backoff +ofdm5gpo=0x33333333 +ofdm5glpo=0x33333333 +ofdm5ghpo=0x33333333 +mcs5gpo0=0x4444 +mcs5gpo1=0x4444 +mcs5glpo0=0x4444 +mcs5glpo1=0x4444 +mcs5ghpo0=0x4444 +mcs5ghpo1=0x4444 +# 5GTxPwr HT40 Backoff +mcs5gpo2=0x6666 +mcs5gpo3=0x6666 +mcs5glpo2=0x6666 +mcs5glpo3=0x6666 +mcs5ghpo2=0x6666 +mcs5ghpo3=0x6666 +# 4334B1FCBGA -16, 4334B2FCBGA 4, 4334B2WLBGA -7 +PwrOffset40mhz5g=-1 + +#ofdmdigfilttype=3 +ofdmdigfilttype2g=3 +ofdmdigfilttype5g=3 +#ofdm40digfilttype=5 -8/21-comment out + +il0macaddr=00:90:4c:c5:12:38 +wl0id=0x431b +pagc2g=0x10 + +# Parameters for DAC2x mode and ALPF bypass +dacrate2xen=1 +txalpfbyp=1 +txalpfpu=1 + +#Murata 2G & 5G FEM switch control table +swctrlmap_2g=0x00400040,0x06060606,0x02020202,0x10302,0x1ff +swctrlmap_5g=0x08080808,0x30303030,0x10101010,0x10302,0x2f8 + +#elna_off_gain_idx_2g=32 +#elna_off_gain_idx_5g=TBD +gain=32 +triso2g=8 +triso5g=7 + +muxenab=0x10 +dacpu.fab.4=1 + +aci_detect_en_2g=1 + +#EPA_or_PAD_lpbck5g=1 +lpbckmode5g=1 +txiqlopapu5g=0 +iqcalidx5g=50 +txiqlopapu2g=0 +dlorange_lowlimit=5 +loflag=1 + +###iqlocalidx5g=50 +###iqlocalidx5g=70 75 80 +iqlocalidx5g=45 + +### dlocalidx5g should be greater than iqlocalidx5g by at least 20 index steps +###dlocalidx5g=90 +dlocalidx5g=65 + +#gain_settle_dly_2g=4 +gain_settle_dly_5g=4 +#noise_cal_po_2g=-1 +#noise_cal_po_40_2g=-1 +#noise_cal_high_gain_2g=73 +#noise_cal_nf_substract_val_2g=346 +noise_cal_po_5g=-1 +noise_cal_po_40_5g=-1 +noise_cal_high_gain_5g=73 +noise_cal_nf_substract_val_5g=346 diff --git a/configs/nvram_mfg.txt_murata b/configs/nvram_mfg.txt_murata new file mode 100755 index 0000000..a5e7448 --- /dev/null +++ b/configs/nvram_mfg.txt_murata @@ -0,0 +1,145 @@ +# Kona Emual Rev0.3 2012.08.21-TSSI + +manfid=0x2d0 +prodid=0x05de +vendid=0x14e4 +devid=0x4380 +boardtype=0x05de +boardrev=0x1205 +boardnum=22 +macaddr=00:90:4c:c5:12:38 +sromrev=3 +#boardflags: 5GHz FEM: has ext 5GHz PA + LNA +# 2.4GHz FEM: has ext 2.4GHz PA + SP3T +# 2.4GHz FEM: SP3T switch share with BT +# keep original 0x200 +boardflags=0x10081a01 +xtalfreq=37400 +nocrc=1 +ag0=0 +aa2g=1 +ccode=ALL +pa0itssit=0x20 +#PA parameters for 2.4GHz-8/21 TSSI +pa0b0=0x14B6 +pa0b1=0xFD8C +pa0b2=0xFF5E + +tssifloor2g=30 +extpagain2g=2 +extpagain5g=2 + +# rssi params for 2.4GHz +rssismf2g=0xf +rssismc2g=0x8 +rssisav2g=0x1 +# rssi params(RFMD) for 2.4GHz +#rssismf2g=0x3 +#rssismc2g=0xa +#rssisav2g=0x1 + +cckPwrOffset=3 +cckdigfilttype=24 +#PwrOffset40mhz2g=-10 +# rssi params for 5GHz +rssismf5g=0xf +rssismc5g=0x7 +rssisav5g=0x1 +#PA parameters for lower a-band-8/21 TSSI +pa1lob0=0x1AF2 +pa1lob1=0xFCC8 +pa1lob2=0xFF52 +tssifloor5gl=30 +#PA parameters for midband-8/21 TSSI +pa1b0=0x1AA0 +pa1b1=0xFCC9 +pa1b2=0xFF45 +tssifloor5gm=30 +#PA paramasdeters for high band-8/21 TSSI +pa1hib0=0x1D27 +pa1hib1=0xFC8E +pa1hib2=0xFF59 +tssifloor5gh=30 +rxpo5g=0 +maxp2ga0=72 +# 2GTxPwr Backoff +ofdm2gpo=0x66666666 +mcs2gpo0=0x8888 +mcs2gpo1=0x8888 +maxp5ga0=66 +maxp5gla0=66 +maxp5gha0=66 +# 5GTxPwr Backoff +ofdm5gpo=0x33333333 +ofdm5glpo=0x33333333 +ofdm5ghpo=0x33333333 +mcs5gpo0=0x4444 +mcs5gpo1=0x4444 +mcs5glpo0=0x4444 +mcs5glpo1=0x4444 +mcs5ghpo0=0x4444 +mcs5ghpo1=0x4444 +# 5GTxPwr HT40 Backoff +mcs5gpo2=0x6666 +mcs5gpo3=0x6666 +mcs5glpo2=0x6666 +mcs5glpo3=0x6666 +mcs5ghpo2=0x6666 +mcs5ghpo3=0x6666 +# 4334B1FCBGA -16, 4334B2FCBGA 4, 4334B2WLBGA -7 +PwrOffset40mhz5g=-7 + +#ofdmdigfilttype=3 +ofdmdigfilttype2g=3 +ofdmdigfilttype5g=3 +#ofdm40digfilttype=5 -8/21-comment out + +il0macaddr=00:90:4c:c5:12:38 +wl0id=0x431b +pagc2g=0x10 + +# Parameters for DAC2x mode and ALPF bypass +dacrate2xen=1 +txalpfbyp=1 +txalpfpu=1 + +#Murata 2G & 5G FEM switch control table +swctrlmap_2g=0x00400040,0x06060606,0x02020202,0x10302,0x1ff +swctrlmap_5g=0x08080808,0x30303030,0x10101010,0x10302,0x2f8 + +elna_off_gain_idx_2g=32 +#elna_off_gain_idx_5g=TBD +triso2g=8 +triso5g=7 + +muxenab=0x10 +dacpu.fab.4=1 + +aci_detect_en_2g=1 + +#EPA_or_PAD_lpbck5g=1 +lpbckmode5g=1 +txiqlopapu5g=0 +iqcalidx5g=50 +txiqlopapu2g=0 +dlorange_lowlimit=5 +loflag=1 + +###iqlocalidx5g=50 +###iqlocalidx5g=70 75 80 +iqlocalidx5g=45 + +### dlocalidx5g should be greater than iqlocalidx5g by at least 20 index steps +###dlocalidx5g=90 +dlocalidx5g=65 + +gain_settle_dly_2g=4 +gain_settle_dly_5g=4 +noise_cal_po_2g=-1 +noise_cal_po_40_2g=-1 +noise_cal_high_gain_2g=73 +noise_cal_nf_substract_val_2g=346 +noise_cal_po_5g=-1 +noise_cal_po_40_5g=-1 +noise_cal_high_gain_5g=73 +noise_cal_nf_substract_val_5g=346 diff --git a/configs/nvram_net.txt b/configs/nvram_net.txt new file mode 100755 index 0000000..e35db20 --- /dev/null +++ b/configs/nvram_net.txt @@ -0,0 +1,152 @@ +# Kona Rev0.1 2012.10.29-TSSI + +manfid=0x2d0 +prodid=0x05de +vendid=0x14e4 +devid=0x4380 +boardtype=0x05de +boardrev=0x1205 +boardnum=22 +macaddr=00:90:4c:c5:12:38 +sromrev=3 +#boardflags: 5GHz FEM: has ext 5GHz PA + LNA +# 2.4GHz FEM: has ext 2.4GHz PA + SP3T +# 2.4GHz FEM: SP3T switch share with BT +# keep original 0x200 +boardflags=0x10081a01 +xtalfreq=37400 +nocrc=1 +ag0=0 +aa2g=1 +ccode=GB +pa0itssit=0x20 +#PA parameters for 2.4GHz-10/29 R01 TSSI +pa0b0=0x141E +pa0b1=0xFD89 +pa0b2=0xFF57 + +tssifloor2g=30 +extpagain2g=2 +extpagain5g=2 + +# rssi params for 2.4GHz +rssismf2g=0xf +rssismc2g=0x8 +rssisav2g=0x1 +# rssi params(RFMD) for 2.4GHz +#rssismf2g=0x3 +#rssismc2g=0xa +#rssisav2g=0x1 + +cckPwrOffset=3 +cckdigfilttype=24 +#PwrOffset40mhz2g=-10 +# rssi params for 5GHz +rssismf5g=0xf +rssismc5g=0x7 +rssisav5g=0x1 +#PA parameters for lower a-band-10/29 R01 TSSI +pa1lob0=0x1A12 +pa1lob1=0xFCE0 +pa1lob2=0xFF53 +tssifloor5gl=30 +#PA parameters for midband-10/29 R01 TSSI +pa1b0=0x1B2F +pa1b1=0xFCBB +pa1b2=0xFF4E +tssifloor5gm=30 +#PA paramasdeters for high band-10/29 R01 TSSI +pa1hib0=0x1BDC +pa1hib1=0xFCA3 +pa1hib2=0xFF4B +tssifloor5gh=30 +rxpo5g=0 +maxp2ga0=72 +# 2GTxPwr Backoff +ofdm2gpo=0x66666666 +mcs2gpo0=0x8888 +mcs2gpo1=0x8888 +maxp5ga0=62 +maxp5gla0=58 +maxp5gha0=54 +# 5GTxPwr Backoff +ofdm5gpo=0x33333333 +ofdm5glpo=0x33333333 +ofdm5ghpo=0x33333333 +mcs5gpo0=0x4444 +mcs5gpo1=0x4444 +mcs5glpo0=0x4444 +mcs5glpo1=0x4444 +mcs5ghpo0=0x4444 +mcs5ghpo1=0x4444 +# 5GTxPwr HT40 Backoff +mcs5gpo2=0x6666 +mcs5gpo3=0x6666 +mcs5glpo2=0x6666 +mcs5glpo3=0x6666 +mcs5ghpo2=0x6666 +mcs5ghpo3=0x6666 +# 4334B1FCBGA -16, 4334B2FCBGA 4, 4334B2WLBGA -7 +PwrOffset40mhz5g=-1 + +#ofdmdigfilttype=3 +ofdmdigfilttype2g=3 +ofdmdigfilttype5g=3 +#ofdm40digfilttype=5 -8/21-comment out + +il0macaddr=00:90:4c:c5:12:38 +wl0id=0x431b +pagc2g=0x10 + +# Parameters for DAC2x mode and ALPF bypass +dacrate2xen=1 +txalpfbyp=1 +txalpfpu=1 + +#Murata 2G & 5G FEM switch control table +swctrlmap_2g=0x00400040,0x06060606,0x02020202,0x10302,0x1ff +swctrlmap_5g=0x08080808,0x30303030,0x10101010,0x10302,0x2f8 + +#elna_off_gain_idx_2g=32 +#elna_off_gain_idx_5g=TBD +gain=32 +triso2g=8 +triso5g=7 + +muxenab=0x10 +dacpu.fab.4=1 + +aci_detect_en_2g=1 + +#EPA_or_PAD_lpbck5g=1 +lpbckmode5g=1 +txiqlopapu5g=0 +iqcalidx5g=50 +txiqlopapu2g=0 +dlorange_lowlimit=5 +loflag=1 + +###iqlocalidx5g=50 +###iqlocalidx5g=70 75 80 +iqlocalidx5g=45 + +### dlocalidx5g should be greater than iqlocalidx5g by at least 20 index steps +###dlocalidx5g=90 +dlocalidx5g=65 + +#gain_settle_dly_2g=4 +gain_settle_dly_5g=4 +#noise_cal_po_2g=-1 +#noise_cal_po_40_2g=-1 +#noise_cal_high_gain_2g=73 +#noise_cal_nf_substract_val_2g=346 +noise_cal_po_5g=-1 +noise_cal_po_40_5g=-1 +noise_cal_high_gain_5g=73 +noise_cal_nf_substract_val_5g=346 + +# BT / WIFI coex parameter + +btc_params80=0 +btc_params6=10 +btc_params95=53 \ No newline at end of file diff --git a/configs/nvram_net.txt_murata b/configs/nvram_net.txt_murata new file mode 100755 index 0000000..28cd6bc --- /dev/null +++ b/configs/nvram_net.txt_murata @@ -0,0 +1,155 @@ +# Kona Emual Rev0.3 2012.08.21-TSSI + +manfid=0x2d0 +prodid=0x05de +vendid=0x14e4 +devid=0x4380 +boardtype=0x05de +boardrev=0x1205 +boardnum=22 +macaddr=00:90:4c:c5:12:38 +sromrev=3 +#boardflags: 5GHz FEM: has ext 5GHz PA + LNA +# 2.4GHz FEM: has ext 2.4GHz PA + SP3T +# 2.4GHz FEM: SP3T switch share with BT +# keep original 0x200 +boardflags=0x10081a01 +xtalfreq=37400 +nocrc=1 +ag0=0 +aa2g=1 +ccode=GB +pa0itssit=0x20 +#PA parameters for 2.4GHz-8/21 TSSI +pa0b0=0x14B6 +pa0b1=0xFD8C +pa0b2=0xFF5E + +tssifloor2g=30 +extpagain2g=2 +extpagain5g=2 + +# rssi params for 2.4GHz +rssismf2g=0xf +rssismc2g=0x8 +rssisav2g=0x1 +# rssi params(RFMD) for 2.4GHz +#rssismf2g=0x3 +#rssismc2g=0xa +#rssisav2g=0x1 + +cckPwrOffset=3 +cckdigfilttype=24 +#PwrOffset40mhz2g=-10 +# rssi params for 5GHz +rssismf5g=0xf +rssismc5g=0x7 +rssisav5g=0x1 +#PA parameters for lower a-band-8/21 TSSI +pa1lob0=0x1AF2 +pa1lob1=0xFCC8 +pa1lob2=0xFF52 +tssifloor5gl=30 +#PA parameters for midband-8/21 TSSI +pa1b0=0x1AA0 +pa1b1=0xFCC9 +pa1b2=0xFF45 +tssifloor5gm=30 +#PA paramasdeters for high band-8/21 TSSI +pa1hib0=0x1D27 +pa1hib1=0xFC8E +pa1hib2=0xFF59 +tssifloor5gh=30 +rxpo5g=0 +maxp2ga0=72 +# 2GTxPwr Backoff +ofdm2gpo=0x66666666 +mcs2gpo0=0x8888 +mcs2gpo1=0x8888 +maxp5ga0=66 +maxp5gla0=66 +maxp5gha0=66 +# 5GTxPwr Backoff +ofdm5gpo=0x33333333 +ofdm5glpo=0x33333333 +ofdm5ghpo=0x33333333 +mcs5gpo0=0x4444 +mcs5gpo1=0x4444 +mcs5glpo0=0x4444 +mcs5glpo1=0x4444 +mcs5ghpo0=0x4444 +mcs5ghpo1=0x4444 +# 5GTxPwr HT40 Backoff +mcs5gpo2=0x6666 +mcs5gpo3=0x6666 +mcs5glpo2=0x6666 +mcs5glpo3=0x6666 +mcs5ghpo2=0x6666 +mcs5ghpo3=0x6666 +# 4334B1FCBGA -16, 4334B2FCBGA 4, 4334B2WLBGA -7 +PwrOffset40mhz5g=-7 + +#ofdmdigfilttype=3 +ofdmdigfilttype2g=3 +ofdmdigfilttype5g=3 +#ofdm40digfilttype=5 -8/21-comment out + +il0macaddr=00:90:4c:c5:12:38 +wl0id=0x431b +pagc2g=0x10 + +# Parameters for DAC2x mode and ALPF bypass +dacrate2xen=1 +txalpfbyp=1 +txalpfpu=1 + +#Murata 2G & 5G FEM switch control table +swctrlmap_2g=0x00400040,0x06060606,0x02020202,0x10302,0x1ff +swctrlmap_5g=0x08080808,0x30303030,0x10101010,0x10302,0x2f8 + +elna_off_gain_idx_2g=32 +#elna_off_gain_idx_5g=TBD +triso2g=8 +triso5g=7 + +muxenab=0x10 +dacpu.fab.4=1 + +aci_detect_en_2g=1 + +#EPA_or_PAD_lpbck5g=1 +lpbckmode5g=1 +txiqlopapu5g=0 +iqcalidx5g=50 +txiqlopapu2g=0 +dlorange_lowlimit=5 +loflag=1 + +###iqlocalidx5g=50 +###iqlocalidx5g=70 75 80 +iqlocalidx5g=45 + +### dlocalidx5g should be greater than iqlocalidx5g by at least 20 index steps +###dlocalidx5g=90 +dlocalidx5g=65 + +gain_settle_dly_2g=4 +gain_settle_dly_5g=4 +noise_cal_po_2g=-1 +noise_cal_po_40_2g=-1 +noise_cal_high_gain_2g=73 +noise_cal_nf_substract_val_2g=346 +noise_cal_po_5g=-1 +noise_cal_po_40_5g=-1 +noise_cal_high_gain_5g=73 +noise_cal_nf_substract_val_5g=346 + +# BT / WIFI coex parameter + +btc_params80=0 + +btc_params6=10 + +btc_params95=53 + + diff --git a/configs/tiny_hw.xml b/configs/tiny_hw.xml new file mode 100755 index 0000000..47d4928 --- /dev/null +++ b/configs/tiny_hw.xml @@ -0,0 +1,340 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extract-files.sh b/extract-files.sh new file mode 100755 index 0000000..53f4411 --- /dev/null +++ b/extract-files.sh @@ -0,0 +1,105 @@ +#!/bin/sh + +# Copyright (C) 2013 The CyanogenMod 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. + +# This file is generated by device/common/generate-blob-scripts.sh - DO NOT EDIT + +VENDOR=samsung +DEVICE=n5100 + +mkdir -p ../../../vendor/$VENDOR/$DEVICE/proprietary + +adb root +adb wait-for-device + +echo "Pulling proprietary files..." +for FILE in `cat ../$DEVICE/proprietary-files.txt | grep -v ^# | grep -v ^$`; do + DIR=`dirname $FILE` + if [ ! -d ../../../vendor/$VENDOR/$DEVICE/proprietary/$DIR ]; then + mkdir -p ../../../vendor/$VENDOR/$DEVICE/proprietary/$DIR + fi + adb pull /$FILE ../../../vendor/$VENDOR/$DEVICE/proprietary/$FILE +done + + +(cat << EOF) | sed s/__DEVICE__/$DEVICE/g | sed s/__VENDOR__/$VENDOR/g > ../../../vendor/$VENDOR/$DEVICE/$DEVICE-vendor-blobs.mk +# Copyright (C) 2013 The CyanogenMod 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 := vendor/__VENDOR__/__DEVICE__ + +PRODUCT_COPY_FILES += \\ +EOF + +LINEEND=" \\" +COUNT=`cat proprietary-files.txt | grep -v ^# | grep -v ^$ | wc -l | awk {'print $1'}` +for FILE in `cat proprietary-files.txt | grep -v ^# | grep -v ^$`; do + COUNT=`expr $COUNT - 1` + if [ $COUNT = "0" ]; then + LINEEND="" + fi + echo " \$(LOCAL_PATH)/proprietary/$FILE:$FILE$LINEEND" >> ../../../vendor/$VENDOR/$DEVICE/$DEVICE-vendor-blobs.mk +done + +(cat << EOF) | sed s/__DEVICE__/$DEVICE/g | sed s/__VENDOR__/$VENDOR/g > ../../../vendor/$VENDOR/$DEVICE/$DEVICE-vendor.mk +# Copyright (C) 2013 The CyanogenMod 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. + +# Pick up overlay for features that depend on non-open-source files +DEVICE_PACKAGE_OVERLAYS += vendor/__VENDOR__/__DEVICE__/overlay + +\$(call inherit-product, vendor/__VENDOR__/__DEVICE__/__DEVICE__-vendor-blobs.mk) +EOF + +(cat << EOF) | sed s/__DEVICE__/$DEVICE/g | sed s/__VENDOR__/$VENDOR/g > ../../../vendor/$VENDOR/$DEVICE/BoardConfigVendor.mk +# Copyright (C) 2013 The CyanogenMod 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. + +EOF + +./../../../device/samsung/smdk4412-common/extract-files.sh diff --git a/full_n5100.mk b/full_n5100.mk new file mode 100644 index 0000000..04ef958 --- /dev/null +++ b/full_n5100.mk @@ -0,0 +1,35 @@ +# Copyright (C) 2012 The CyanogenMod 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. + +# +# This file is the build configuration for a full Android +# build for toro hardware. This cleanly combines a set of +# device-specific aspects (drivers) with a device-agnostic +# product configuration (apps). Except for a few implementation +# details, it only fundamentally contains two inherit-product +# lines, full and toro, hence its name. +# + +# Inherit from those products. Most specific first. +$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base_telephony.mk) +# This is where we'd set a backup provider if we had one +#$(call inherit-product, device/sample/products/backup_overlay.mk) +$(call inherit-product, device/samsung/n5100/n5100.mk) + +# Discard inherited values and use our own instead. +PRODUCT_NAME := full_n5100 +PRODUCT_DEVICE := n5100 +PRODUCT_BRAND := samsung +PRODUCT_MANUFACTURER := samsung +PRODUCT_MODEL := GT-N5100 diff --git a/include/hardware/gps.h b/include/hardware/gps.h new file mode 100755 index 0000000..ba6eb5c --- /dev/null +++ b/include/hardware/gps.h @@ -0,0 +1,949 @@ +/* + * Copyright (C) 2010 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 ANDROID_INCLUDE_HARDWARE_GPS_H +#define ANDROID_INCLUDE_HARDWARE_GPS_H + +#include +#include +#include +#include + +#include + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define GPS_HARDWARE_MODULE_ID "gps" + + +/** Milliseconds since January 1, 1970 */ +typedef int64_t GpsUtcTime; + +/** Maximum number of SVs for gps_sv_status_callback(). */ +#define GPS_MAX_SVS 32 + +/** Requested operational mode for GPS operation. */ +typedef uint32_t GpsPositionMode; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** Mode for running GPS standalone (no assistance). */ +#define GPS_POSITION_MODE_STANDALONE 0 +/** AGPS MS-Based mode. */ +#define GPS_POSITION_MODE_MS_BASED 1 +/** AGPS MS-Assisted mode. */ +#define GPS_POSITION_MODE_MS_ASSISTED 2 + +/** Requested recurrence mode for GPS operation. */ +typedef uint32_t GpsPositionRecurrence; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** Receive GPS fixes on a recurring basis at a specified period. */ +#define GPS_POSITION_RECURRENCE_PERIODIC 0 +/** Request a single shot GPS fix. */ +#define GPS_POSITION_RECURRENCE_SINGLE 1 + +/** GPS status event values. */ +typedef uint16_t GpsStatusValue; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** GPS status unknown. */ +#define GPS_STATUS_NONE 0 +/** GPS has begun navigating. */ +#define GPS_STATUS_SESSION_BEGIN 1 +/** GPS has stopped navigating. */ +#define GPS_STATUS_SESSION_END 2 +/** GPS has powered on but is not navigating. */ +#define GPS_STATUS_ENGINE_ON 3 +/** GPS is powered off. */ +#define GPS_STATUS_ENGINE_OFF 4 + +/** Flags to indicate which values are valid in a GpsLocation. */ +typedef uint16_t GpsLocationFlags; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** GpsLocation has valid latitude and longitude. */ +#define GPS_LOCATION_HAS_LAT_LONG 0x0001 +/** GpsLocation has valid altitude. */ +#define GPS_LOCATION_HAS_ALTITUDE 0x0002 +/** GpsLocation has valid speed. */ +#define GPS_LOCATION_HAS_SPEED 0x0004 +/** GpsLocation has valid bearing. */ +#define GPS_LOCATION_HAS_BEARING 0x0008 +/** GpsLocation has valid accuracy. */ +#define GPS_LOCATION_HAS_ACCURACY 0x0010 + +/** Flags for the gps_set_capabilities callback. */ + +/** GPS HAL schedules fixes for GPS_POSITION_RECURRENCE_PERIODIC mode. + If this is not set, then the framework will use 1000ms for min_interval + and will start and call start() and stop() to schedule the GPS. + */ +#define GPS_CAPABILITY_SCHEDULING 0x0000001 +/** GPS supports MS-Based AGPS mode */ +#define GPS_CAPABILITY_MSB 0x0000002 +/** GPS supports MS-Assisted AGPS mode */ +#define GPS_CAPABILITY_MSA 0x0000004 +/** GPS supports single-shot fixes */ +#define GPS_CAPABILITY_SINGLE_SHOT 0x0000008 +/** GPS supports on demand time injection */ +#define GPS_CAPABILITY_ON_DEMAND_TIME 0x0000010 + +/** Flags used to specify which aiding data to delete + when calling delete_aiding_data(). */ +typedef uint16_t GpsAidingData; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +#define GPS_DELETE_EPHEMERIS 0x0001 +#define GPS_DELETE_ALMANAC 0x0002 +#define GPS_DELETE_POSITION 0x0004 +#define GPS_DELETE_TIME 0x0008 +#define GPS_DELETE_IONO 0x0010 +#define GPS_DELETE_UTC 0x0020 +#define GPS_DELETE_HEALTH 0x0040 +#define GPS_DELETE_SVDIR 0x0080 +#define GPS_DELETE_SVSTEER 0x0100 +#define GPS_DELETE_SADATA 0x0200 +#define GPS_DELETE_RTI 0x0400 +#define GPS_DELETE_CELLDB_INFO 0x8000 +#define GPS_DELETE_ALL 0xFFFF + +/** AGPS type */ +typedef uint16_t AGpsType; +#define AGPS_TYPE_SUPL 1 +#define AGPS_TYPE_C2K 2 + +typedef uint16_t AGpsSetIDType; +#define AGPS_SETID_TYPE_NONE 0 +#define AGPS_SETID_TYPE_IMSI 1 +#define AGPS_SETID_TYPE_MSISDN 2 + +/** + * String length constants + */ +#define GPS_NI_SHORT_STRING_MAXLEN 256 +#define GPS_NI_LONG_STRING_MAXLEN 2048 + +/** + * GpsNiType constants + */ +typedef uint32_t GpsNiType; +#define GPS_NI_TYPE_VOICE 1 +#define GPS_NI_TYPE_UMTS_SUPL 2 +#define GPS_NI_TYPE_UMTS_CTRL_PLANE 3 + +/** + * GpsNiNotifyFlags constants + */ +typedef uint32_t GpsNiNotifyFlags; +/** NI requires notification */ +#define GPS_NI_NEED_NOTIFY 0x0001 +/** NI requires verification */ +#define GPS_NI_NEED_VERIFY 0x0002 +/** NI requires privacy override, no notification/minimal trace */ +#define GPS_NI_PRIVACY_OVERRIDE 0x0004 + +/** + * GPS NI responses, used to define the response in + * NI structures + */ +typedef int GpsUserResponseType; +#define GPS_NI_RESPONSE_ACCEPT 1 +#define GPS_NI_RESPONSE_DENY 2 +#define GPS_NI_RESPONSE_NORESP 3 + +/** + * NI data encoding scheme + */ +typedef int GpsNiEncodingType; +#define GPS_ENC_NONE 0 +#define GPS_ENC_SUPL_GSM_DEFAULT 1 +#define GPS_ENC_SUPL_UTF8 2 +#define GPS_ENC_SUPL_UCS2 3 +#define GPS_ENC_UNKNOWN -1 + +/** AGPS status event values. */ +typedef uint16_t AGpsStatusValue; +/** GPS requests data connection for AGPS. */ +#define GPS_REQUEST_AGPS_DATA_CONN 1 +/** GPS releases the AGPS data connection. */ +#define GPS_RELEASE_AGPS_DATA_CONN 2 +/** AGPS data connection initiated */ +#define GPS_AGPS_DATA_CONNECTED 3 +/** AGPS data connection completed */ +#define GPS_AGPS_DATA_CONN_DONE 4 +/** AGPS data connection failed */ +#define GPS_AGPS_DATA_CONN_FAILED 5 + +#define AGPS_REF_LOCATION_TYPE_GSM_CELLID 1 +#define AGPS_REF_LOCATION_TYPE_UMTS_CELLID 2 +#define AGPS_REG_LOCATION_TYPE_MAC 3 + +/** Network types for update_network_state "type" parameter */ +#define AGPS_RIL_NETWORK_TYPE_MOBILE 0 +#define AGPS_RIL_NETWORK_TYPE_WIFI 1 +#define AGPS_RIL_NETWORK_TYPE_MOBILE_MMS 2 +#define AGPS_RIL_NETWORK_TYPE_MOBILE_SUPL 3 +#define AGPS_RIL_NETWORK_TTYPE_MOBILE_DUN 4 +#define AGPS_RIL_NETWORK_TTYPE_MOBILE_HIPRI 5 +#define AGPS_RIL_NETWORK_TTYPE_WIMAX 6 + +/** + * Name for the GPS XTRA interface. + */ +#define GPS_XTRA_INTERFACE "gps-xtra" + +/** + * Name for the GPS DEBUG interface. + */ +#define GPS_DEBUG_INTERFACE "gps-debug" + +/** + * Name for the AGPS interface. + */ +#define AGPS_INTERFACE "agps" + +/** + * Name for NI interface + */ +#define GPS_NI_INTERFACE "gps-ni" + +/** + * Name for the AGPS-RIL interface. + */ +#define AGPS_RIL_INTERFACE "agps_ril" + +/** + * The GPS chipset can use Psc for AGPS. + */ +#define AGPS_USE_PSC + +/* + * Name for the GPS_Geofencing interface. + */ +#define GPS_GEOFENCING_INTERFACE "gps_geofencing" + +/** Represents a location. */ +typedef struct { + /** set to sizeof(GpsLocation) */ + size_t size; + /** Contains GpsLocationFlags bits. */ + uint16_t flags; + /** Represents latitude in degrees. */ + double latitude; + /** Represents longitude in degrees. */ + double longitude; + /** Represents altitude in meters above the WGS 84 reference + * ellipsoid. */ + double altitude; + /** Represents speed in meters per second. */ + float speed; + /** Represents heading in degrees. */ + float bearing; + /** Represents expected accuracy in meters. */ + float accuracy; + /** Timestamp for the location fix. */ + GpsUtcTime timestamp; +} GpsLocation; + +/** Represents the status. */ +typedef struct { + /** set to sizeof(GpsStatus) */ + size_t size; + GpsStatusValue status; +} GpsStatus; + +/** Represents SV information. */ +typedef struct { + /** set to sizeof(GpsSvInfo) */ + size_t size; + /** Pseudo-random number for the SV. */ + int prn; + /** Signal to noise ratio. */ + float snr; + /** Elevation of SV in degrees. */ + float elevation; + /** Azimuth of SV in degrees. */ + float azimuth; + /** Unknown field in Samsung I9100 libgps + May be an indicator for constellation type + (GPS, GLONASS, Galileo)? + Used on GT-I9100, likely also present on GT-N7000, + SGH-I717, SGH-I727 but this needs confirmation. + */ + int unknown_samsung_field; +} GpsSvInfo; + +/** Represents SV status. */ +typedef struct { + /** set to sizeof(GpsSvStatus) */ + size_t size; + + /** Number of SVs currently visible. */ + int num_svs; + + /** Contains an array of SV information. */ + GpsSvInfo sv_list[GPS_MAX_SVS]; + + /** Represents a bit mask indicating which SVs + * have ephemeris data. + */ + uint32_t ephemeris_mask; + + /** Represents a bit mask indicating which SVs + * have almanac data. + */ + uint32_t almanac_mask; + + /** + * Represents a bit mask indicating which SVs + * were used for computing the most recent position fix. + */ + uint32_t used_in_fix_mask; +} GpsSvStatus; + +/* 2G and 3G */ +/* In 3G lac is discarded */ +typedef struct { + uint16_t type; + uint16_t mcc; + uint16_t mnc; + uint16_t lac; +#ifdef AGPS_USE_PSC + uint16_t psc; +#endif + uint32_t cid; +} AGpsRefLocationCellID; + +typedef struct { + uint8_t mac[6]; +} AGpsRefLocationMac; + +/** Represents ref locations */ +typedef struct { + uint16_t type; + union { + AGpsRefLocationCellID cellID; + AGpsRefLocationMac mac; + } u; +} AGpsRefLocation; + +/** Callback with location information. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* gps_location_callback)(GpsLocation* location); + +/** Callback with status information. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* gps_status_callback)(GpsStatus* status); + +/** Callback with SV status information. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info); + +/** Callback for reporting NMEA sentences. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* gps_nmea_callback)(GpsUtcTime timestamp, const char* nmea, int length); + +/** Callback to inform framework of the GPS engine's capabilities. + * Capability parameter is a bit field of GPS_CAPABILITY_* flags. + */ +typedef void (* gps_set_capabilities)(uint32_t capabilities); + +/** Callback utility for acquiring the GPS wakelock. + * This can be used to prevent the CPU from suspending while handling GPS events. + */ +typedef void (* gps_acquire_wakelock)(); + +/** Callback utility for releasing the GPS wakelock. */ +typedef void (* gps_release_wakelock)(); + +/** Callback for requesting NTP time */ +typedef void (* gps_request_utc_time)(); + +/** Callback for creating a thread that can call into the Java framework code. + * This must be used to create any threads that report events up to the framework. + */ +typedef pthread_t (* gps_create_thread)(const char* name, void (*start)(void *), void* arg); + +/** GPS callback structure. */ +typedef struct { + /** set to sizeof(GpsCallbacks) */ + size_t size; + gps_location_callback location_cb; + gps_status_callback status_cb; + gps_sv_status_callback sv_status_cb; + gps_nmea_callback nmea_cb; + gps_set_capabilities set_capabilities_cb; + gps_acquire_wakelock acquire_wakelock_cb; + gps_release_wakelock release_wakelock_cb; + gps_create_thread create_thread_cb; + gps_request_utc_time request_utc_time_cb; +} GpsCallbacks; + + +/** Represents the standard GPS interface. */ +typedef struct { + /** set to sizeof(GpsInterface) */ + size_t size; + /** + * Opens the interface and provides the callback routines + * to the implemenation of this interface. + */ + int (*init)( GpsCallbacks* callbacks ); + + /** Starts navigating. */ + int (*start)( void ); + + /** Stops navigating. */ + int (*stop)( void ); + + /** Closes the interface. */ + void (*cleanup)( void ); + + /** Injects the current time. */ + int (*inject_time)(GpsUtcTime time, int64_t timeReference, + int uncertainty); + + /** Injects current location from another location provider + * (typically cell ID). + * latitude and longitude are measured in degrees + * expected accuracy is measured in meters + */ + int (*inject_location)(double latitude, double longitude, float accuracy); + + /** + * Specifies that the next call to start will not use the + * information defined in the flags. GPS_DELETE_ALL is passed for + * a cold start. + */ + void (*delete_aiding_data)(GpsAidingData flags); + + /** + * min_interval represents the time between fixes in milliseconds. + * preferred_accuracy represents the requested fix accuracy in meters. + * preferred_time represents the requested time to first fix in milliseconds. + */ + int (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence, + uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time); + + /** Get a pointer to extension information. */ + const void* (*get_extension)(const char* name); +} GpsInterface; + +/** Callback to request the client to download XTRA data. + * The client should download XTRA data and inject it by calling inject_xtra_data(). + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* gps_xtra_download_request)(); + +/** Callback structure for the XTRA interface. */ +typedef struct { + gps_xtra_download_request download_request_cb; + gps_create_thread create_thread_cb; +} GpsXtraCallbacks; + +/** Extended interface for XTRA support. */ +typedef struct { + /** set to sizeof(GpsXtraInterface) */ + size_t size; + /** + * Opens the XTRA interface and provides the callback routines + * to the implemenation of this interface. + */ + int (*init)( GpsXtraCallbacks* callbacks ); + /** Injects XTRA data into the GPS. */ + int (*inject_xtra_data)( char* data, int length ); +} GpsXtraInterface; + +/** Extended interface for DEBUG support. */ +typedef struct { + /** set to sizeof(GpsDebugInterface) */ + size_t size; + + /** + * This function should return any information that the native + * implementation wishes to include in a bugreport. + */ + size_t (*get_internal_state)(char* buffer, size_t bufferSize); +} GpsDebugInterface; + +/** Represents the status of AGPS. */ +typedef struct { + /** set to sizeof(AGpsStatus) */ + size_t size; + + AGpsType type; + AGpsStatusValue status; + uint32_t ipaddr; +} AGpsStatus; + +/** Callback with AGPS status information. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* agps_status_callback)(AGpsStatus* status); + +/** Callback structure for the AGPS interface. */ +typedef struct { + agps_status_callback status_cb; + gps_create_thread create_thread_cb; +} AGpsCallbacks; + + +/** Extended interface for AGPS support. */ +typedef struct { + /** set to sizeof(AGpsInterface) */ + size_t size; + + /** + * Opens the AGPS interface and provides the callback routines + * to the implemenation of this interface. + */ + void (*init)( AGpsCallbacks* callbacks ); + /** + * Notifies that a data connection is available and sets + * the name of the APN to be used for SUPL. + */ + int (*data_conn_open)( const char* apn ); + /** + * Notifies that the AGPS data connection has been closed. + */ + int (*data_conn_closed)(); + /** + * Notifies that a data connection is not available for AGPS. + */ + int (*data_conn_failed)(); + /** + * Sets the hostname and port for the AGPS server. + */ + int (*set_server)( AGpsType type, const char* hostname, int port ); +} AGpsInterface; + + +/** Represents an NI request */ +typedef struct { + /** set to sizeof(GpsNiNotification) */ + size_t size; + + /** + * An ID generated by HAL to associate NI notifications and UI + * responses + */ + int notification_id; + + /** + * An NI type used to distinguish different categories of NI + * events, such as GPS_NI_TYPE_VOICE, GPS_NI_TYPE_UMTS_SUPL, ... + */ + GpsNiType ni_type; + + /** + * Notification/verification options, combinations of GpsNiNotifyFlags constants + */ + GpsNiNotifyFlags notify_flags; + + /** + * Timeout period to wait for user response. + * Set to 0 for no time out limit. + */ + int timeout; + + /** + * Default response when time out. + */ + GpsUserResponseType default_response; + + /** + * Requestor ID + */ + char requestor_id[GPS_NI_SHORT_STRING_MAXLEN]; + + /** + * Notification message. It can also be used to store client_id in some cases + */ + char text[GPS_NI_LONG_STRING_MAXLEN]; + + /** + * Client name decoding scheme + */ + GpsNiEncodingType requestor_id_encoding; + + /** + * Client name decoding scheme + */ + GpsNiEncodingType text_encoding; + + /** + * A pointer to extra data. Format: + * key_1 = value_1 + * key_2 = value_2 + */ + char extras[GPS_NI_LONG_STRING_MAXLEN]; + +} GpsNiNotification; + +/** Callback with NI notification. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (*gps_ni_notify_callback)(GpsNiNotification *notification); + +/** GPS NI callback structure. */ +typedef struct +{ + /** + * Sends the notification request from HAL to GPSLocationProvider. + */ + gps_ni_notify_callback notify_cb; + gps_create_thread create_thread_cb; +} GpsNiCallbacks; + +/** + * Extended interface for Network-initiated (NI) support. + */ +typedef struct +{ + /** set to sizeof(GpsNiInterface) */ + size_t size; + + /** Registers the callbacks for HAL to use. */ + void (*init) (GpsNiCallbacks *callbacks); + + /** Sends a response to HAL. */ + void (*respond) (int notif_id, GpsUserResponseType user_response); +} GpsNiInterface; + +struct gps_device_t { + struct hw_device_t common; + + /** + * Set the provided lights to the provided values. + * + * Returns: 0 on succes, error code on failure. + */ + const GpsInterface* (*get_gps_interface)(struct gps_device_t* dev); +}; + +#define AGPS_RIL_REQUEST_SETID_IMSI (1<<0L) +#define AGPS_RIL_REQUEST_SETID_MSISDN (1<<1L) + +#define AGPS_RIL_REQUEST_REFLOC_CELLID (1<<0L) +#define AGPS_RIL_REQUEST_REFLOC_MAC (1<<1L) + +typedef void (*agps_ril_request_set_id)(uint32_t flags); +typedef void (*agps_ril_request_ref_loc)(uint32_t flags); + +typedef struct { + agps_ril_request_set_id request_setid; + agps_ril_request_ref_loc request_refloc; + gps_create_thread create_thread_cb; +} AGpsRilCallbacks; + +/** Extended interface for AGPS_RIL support. */ +typedef struct { + /** set to sizeof(AGpsRilInterface) */ + size_t size; + /** + * Opens the AGPS interface and provides the callback routines + * to the implemenation of this interface. + */ + void (*init)( AGpsRilCallbacks* callbacks ); + + /** + * Sets the reference location. + */ + void (*set_ref_location) (const AGpsRefLocation *agps_reflocation, size_t sz_struct); + /** + * Sets the set ID. + */ + void (*set_set_id) (AGpsSetIDType type, const char* setid); + + /** + * Send network initiated message. + */ + void (*ni_message) (uint8_t *msg, size_t len); + + /** + * Notify GPS of network status changes. + * These parameters match values in the android.net.NetworkInfo class. + */ + void (*update_network_state) (int connected, int type, int roaming, const char* extra_info); + + /** + * Notify GPS of network status changes. + * These parameters match values in the android.net.NetworkInfo class. + */ + void (*update_network_availability) (int avaiable, const char* apn); +} AGpsRilInterface; +/** + * GPS Geofence. + * There are 3 states associated with a Geofence: Inside, Outside, Unknown. + * There are 3 transitions: ENTERED, EXITED, UNCERTAIN. + * + * An example state diagram with confidence level: 95% and Unknown time limit + * set as 30 secs is shown below. (confidence level and Unknown time limit are + * explained latter) + * ____________________________ + * | Unknown (30 secs) | + * """""""""""""""""""""""""""" + * ^ | | ^ + * UNCERTAIN| |ENTERED EXITED| |UNCERTAIN + * | v v | + * ________ EXITED _________ + * | Inside | -----------> | Outside | + * | | <----------- | | + * """""""" ENTERED """"""""" + * + * Inside state: We are 95% confident that the user is inside the geofence. + * Outside state: We are 95% confident that the user is outside the geofence + * Unknown state: Rest of the time. + * + * The Unknown state is better explained with an example: + * + * __________ + * | c| + * | ___ | _______ + * | |a| | | b | + * | """ | """"""" + * | | + * """""""""" + * In the diagram above, "a" and "b" are 2 geofences and "c" is the accuracy + * circle reported by the GPS subsystem. Now with regard to "b", the system is + * confident that the user is outside. But with regard to "a" is not confident + * whether it is inside or outside the geofence. If the accuracy remains the + * same for a sufficient period of time, the UNCERTAIN transition would be + * triggered with the state set to Unknown. If the accuracy improves later, an + * appropriate transition should be triggered. This "sufficient period of time" + * is defined by the parameter in the add_geofence_area API. + * In other words, Unknown state can be interpreted as a state in which the + * GPS subsystem isn't confident enough that the user is either inside or + * outside the Geofence. It moves to Unknown state only after the expiry of the + * timeout. + * + * The geofence callback needs to be triggered for the ENTERED and EXITED + * transitions, when the GPS system is confident that the user has entered + * (Inside state) or exited (Outside state) the Geofence. An implementation + * which uses a value of 95% as the confidence is recommended. The callback + * should be triggered only for the transitions requested by the + * add_geofence_area call. + * + * Even though the diagram and explanation talks about states and transitions, + * the callee is only interested in the transistions. The states are mentioned + * here for illustrative purposes. + * + * Startup Scenario: When the device boots up, if an application adds geofences, + * and then we get an accurate GPS location fix, it needs to trigger the + * appropriate (ENTERED or EXITED) transition for every Geofence it knows about. + * By default, all the Geofences will be in the Unknown state. + * + * When the GPS system is unavailable, gps_geofence_status_callback should be + * called to inform the upper layers of the same. Similarly, when it becomes + * available the callback should be called. This is a global state while the + * UNKNOWN transition described above is per geofence. + * + * An important aspect to note is that users of this API (framework), will use + * other subsystems like wifi, sensors, cell to handle Unknown case and + * hopefully provide a definitive state transition to the third party + * application. GPS Geofence will just be a signal indicating what the GPS + * subsystem knows about the Geofence. + * + */ +#define GPS_GEOFENCE_ENTERED (1<<0L) +#define GPS_GEOFENCE_EXITED (1<<1L) +#define GPS_GEOFENCE_UNCERTAIN (1<<2L) + +#define GPS_GEOFENCE_UNAVAILABLE (1<<0L) +#define GPS_GEOFENCE_AVAILABLE (1<<1L) + +#define GPS_GEOFENCE_OPERATION_SUCCESS 0 +#define GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES -100 +#define GPS_GEOFENCE_ERROR_ID_EXISTS -101 +#define GPS_GEOFENCE_ERROR_ID_UNKNOWN -102 +#define GPS_GEOFENCE_ERROR_INVALID_TRANSITION -103 +#define GPS_GEOFENCE_ERROR_GENERIC -149 +/** +* The callback associated with the geofence. +* Parameters: +* geofence_id - The id associated with the add_geofence_area. +* location - The current GPS location. +* transition - Can be one of GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED, +* GPS_GEOFENCE_UNCERTAIN. +* timestamp - Timestamp when the transition was detected. +* +* The callback should only be called when the caller is interested in that +* particular transition. For instance, if the caller is interested only in +* ENTERED transition, then the callback should NOT be called with the EXITED +* transition. +* +* IMPORTANT: If a transition is triggered resulting in this callback, the GPS +* subsystem will wake up the application processor, if its in suspend state. +*/ +typedef void (*gps_geofence_transition_callback) (int32_t geofence_id, GpsLocation* location, +int32_t transition, GpsUtcTime timestamp); + +/** + * The callback associated with the availablity of the GPS system for geofencing + * monitoring. If the GPS system determines that it cannot monitor geofences + * because of lack of reliability or unavailability of the GPS signals, it will + * call this callback with GPS_GEOFENCE_UNAVAILABLE parameter. + * + * Parameters: + * status - GPS_GEOFENCE_UNAVAILABLE or GPS_GEOFENCE_AVAILABLE. + * last_location - Last known location. + */ +typedef void (*gps_geofence_status_callback) (int32_t status, GpsLocation* last_location); + +/** + * The callback associated with the add_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * status - GPS_GEOFENCE_OPERATION_SUCCESS + * GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES - geofence limit has been reached. + * GPS_GEOFENCE_ERROR_ID_EXISTS - geofence with id already exists + * GPS_GEOFENCE_ERROR_INVALID_TRANSITION - the monitorTransition contains an + * invalid transition + * GPS_GEOFENCE_ERROR_GENERIC - for other errors. + */ +typedef void (*gps_geofence_add_callback) (int32_t geofence_id, int32_t status); + +/** + * The callback associated with the remove_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * status - GPS_GEOFENCE_OPERATION_SUCCESS + * GPS_GEOFENCE_ERROR_ID_UNKNOWN - for invalid id + * GPS_GEOFENCE_ERROR_GENERIC for others. + */ +typedef void (*gps_geofence_remove_callback) (int32_t geofence_id, int32_t status); + + +/** + * The callback associated with the pause_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * status - GPS_GEOFENCE_OPERATION_SUCCESS + * GPS_GEOFENCE_ERROR_ID_UNKNOWN - for invalid id + * GPS_GEOFENCE_ERROR_INVALID_TRANSITION - + * when monitor_transitions is invalid + * GPS_GEOFENCE_ERROR_GENERIC for others. + */ +typedef void (*gps_geofence_pause_callback) (int32_t geofence_id, int32_t status); + +/** + * The callback associated with the resume_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * status - GPS_GEOFENCE_OPERATION_SUCCESS + * GPS_GEOFENCE_ERROR_ID_UNKNOWN - for invalid id + * GPS_GEOFENCE_ERROR_GENERIC for others. + */ +typedef void (*gps_geofence_resume_callback) (int32_t geofence_id, int32_t status); + +typedef struct { + gps_geofence_transition_callback geofence_transition_callback; + gps_geofence_status_callback geofence_status_callback; + gps_geofence_add_callback geofence_add_callback; + gps_geofence_remove_callback geofence_remove_callback; + gps_geofence_pause_callback geofence_pause_callback; + gps_geofence_resume_callback geofence_resume_callback; + gps_create_thread create_thread_cb; +} GpsGeofenceCallbacks; + +/** Extended interface for GPS_Geofencing support */ +typedef struct { + /** set to sizeof(GpsGeofencingInterface) */ + size_t size; + + /** + * Opens the geofence interface and provides the callback routines + * to the implemenation of this interface. + */ + void (*init)( GpsGeofenceCallbacks* callbacks ); + + /** + * Add a geofence area. This api currently supports circular geofences. + * Parameters: + * geofence_id - The id for the geofence. If a geofence with this id + * already exists, an error value (GPS_GEOFENCE_ERROR_ID_EXISTS) + * should be returned. + * latitude, longtitude, radius_meters - The lat, long and radius + * (in meters) for the geofence + * last_transition - The current state of the geofence. For example, if + * the system already knows that the user is inside the geofence, + * this will be set to GPS_GEOFENCE_ENTERED. In most cases, it + * will be GPS_GEOFENCE_UNCERTAIN. + * monitor_transition - Which transitions to monitor. Bitwise OR of + * GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED and + * GPS_GEOFENCE_UNCERTAIN. + * notification_responsiveness_ms - Defines the best-effort description + * of how soon should the callback be called when the transition + * associated with the Geofence is triggered. For instance, if set + * to 1000 millseconds with GPS_GEOFENCE_ENTERED, the callback + * should be called 1000 milliseconds within entering the geofence. + * This parameter is defined in milliseconds. + * NOTE: This is not to be confused with the rate that the GPS is + * polled at. It is acceptable to dynamically vary the rate of + * sampling the GPS for power-saving reasons; thus the rate of + * sampling may be faster or slower than this. + * unknown_timer_ms - The time limit after which the UNCERTAIN transition + * should be triggered. This paramter is defined in milliseconds. + * See above for a detailed explanation. + */ + void (*add_geofence_area) (int32_t geofence_id, double latitude, + double longitude, double radius_meters, + int last_transition, int monitor_transitions, + int notification_responsiveness_ms, + int unknown_timer_ms); + + /** + * Pause monitoring a particular geofence. + * Parameters: + * geofence_id - The id for the geofence. + */ + void (*pause_geofence) (int32_t geofence_id); + + /** + * Resume monitoring a particular geofence. + * Parameters: + * geofence_id - The id for the geofence. + * monitor_transitions - Which transitions to monitor. Bitwise OR of + * GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED and + * GPS_GEOFENCE_UNCERTAIN. + * This supersedes the value associated provided in the + * add_geofence_area call. + */ + void (*resume_geofence) (int32_t geofence_id, int monitor_transitions); + + /** + * Remove a geofence area. After the function returns, no notifications + * should be sent. + * Parameter: + * geofence_id - The id for the geofence. + */ + void (*remove_geofence_area) (int32_t geofence_id); +} GpsGeofencingInterface; +__END_DECLS + +#endif /* ANDROID_INCLUDE_HARDWARE_GPS_H */ + diff --git a/include/telephony/ril.h b/include/telephony/ril.h new file mode 100644 index 0000000..fefc563 --- /dev/null +++ b/include/telephony/ril.h @@ -0,0 +1,4252 @@ +/* + * Copyright (C) 2006 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 ANDROID_RIL_H +#define ANDROID_RIL_H 1 + +#include +#include +#ifndef FEATURE_UNIT_TEST +#include +#endif /* !FEATURE_UNIT_TEST */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define RIL_VERSION 8 /* Current version */ +#ifdef LEGACY_RIL +#define RIL_VERSION_MIN 2 /* Minimum RIL_VERSION supported */ +#else +#define RIL_VERSION_MIN 6 /* Minimum RIL_VERSION supported */ +#endif + +#define CDMA_ALPHA_INFO_BUFFER_LENGTH 64 +#define CDMA_NUMBER_INFO_BUFFER_LENGTH 81 + +typedef void * RIL_Token; + +typedef enum { + RIL_E_SUCCESS = 0, + RIL_E_RADIO_NOT_AVAILABLE = 1, /* If radio did not start or is resetting */ + RIL_E_GENERIC_FAILURE = 2, + RIL_E_PASSWORD_INCORRECT = 3, /* for PIN/PIN2 methods only! */ + RIL_E_SIM_PIN2 = 4, /* Operation requires SIM PIN2 to be entered */ + RIL_E_SIM_PUK2 = 5, /* Operation requires SIM PIN2 to be entered */ + RIL_E_REQUEST_NOT_SUPPORTED = 6, + RIL_E_CANCELLED = 7, + RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL = 8, /* data ops are not allowed during voice + call on a Class C GPRS device */ + RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9, /* data ops are not allowed before device + registers in network */ + RIL_E_SMS_SEND_FAIL_RETRY = 10, /* fail to send sms and need retry */ + RIL_E_SIM_ABSENT = 11, /* fail to set the location where CDMA subscription + shall be retrieved because of SIM or RUIM + card absent */ + RIL_E_SUBSCRIPTION_NOT_AVAILABLE = 12, /* fail to find CDMA subscription from specified + location */ + RIL_E_MODE_NOT_SUPPORTED = 13, /* HW does not support preferred network type */ + RIL_E_FDN_CHECK_FAILURE = 14, /* command failed because recipient is not on FDN list */ + RIL_E_ILLEGAL_SIM_OR_ME = 15 /* network selection failed due to + illegal SIM or ME */ +} RIL_Errno; + +typedef enum { + RIL_CALL_ACTIVE = 0, + RIL_CALL_HOLDING = 1, + RIL_CALL_DIALING = 2, /* MO call only */ + RIL_CALL_ALERTING = 3, /* MO call only */ + RIL_CALL_INCOMING = 4, /* MT call only */ + RIL_CALL_WAITING = 5 /* MT call only */ +} RIL_CallState; + +typedef enum { + RADIO_STATE_OFF = 0, /* Radio explictly powered off (eg CFUN=0) */ + RADIO_STATE_UNAVAILABLE = 1, /* Radio unavailable (eg, resetting or not booted) */ + /* States 2-9 below are deprecated. Just leaving them here for backward compatibility. */ + RADIO_STATE_SIM_NOT_READY = 2, /* Radio is on, but the SIM interface is not ready */ + RADIO_STATE_SIM_LOCKED_OR_ABSENT = 3, /* SIM PIN locked, PUK required, network + personalization locked, or SIM absent */ + RADIO_STATE_SIM_READY = 4, /* Radio is on and SIM interface is available */ + RADIO_STATE_RUIM_NOT_READY = 5, /* Radio is on, but the RUIM interface is not ready */ + RADIO_STATE_RUIM_READY = 6, /* Radio is on and the RUIM interface is available */ + RADIO_STATE_RUIM_LOCKED_OR_ABSENT = 7, /* RUIM PIN locked, PUK required, network + personalization locked, or RUIM absent */ + RADIO_STATE_NV_NOT_READY = 8, /* Radio is on, but the NV interface is not available */ + RADIO_STATE_NV_READY = 9, /* Radio is on and the NV interface is available */ + RADIO_STATE_ON = 10 /* Radio is on */ +} RIL_RadioState; + +typedef enum { + RADIO_TECH_UNKNOWN = 0, + RADIO_TECH_GPRS = 1, + RADIO_TECH_EDGE = 2, + RADIO_TECH_UMTS = 3, + RADIO_TECH_IS95A = 4, + RADIO_TECH_IS95B = 5, + RADIO_TECH_1xRTT = 6, + RADIO_TECH_EVDO_0 = 7, + RADIO_TECH_EVDO_A = 8, + RADIO_TECH_HSDPA = 9, + RADIO_TECH_HSUPA = 10, + RADIO_TECH_HSPA = 11, + RADIO_TECH_EVDO_B = 12, + RADIO_TECH_EHRPD = 13, + RADIO_TECH_LTE = 14, + RADIO_TECH_HSPAP = 15, // HSPA+ + RADIO_TECH_GSM = 16, // Only supports voice + RADIO_TECH_DCHSPAP = 30 +} RIL_RadioTechnology; + +// Do we want to split Data from Voice and the use +// RIL_RadioTechnology for get/setPreferredVoice/Data ? +typedef enum { + PREF_NET_TYPE_GSM_WCDMA = 0, /* GSM/WCDMA (WCDMA preferred) */ + PREF_NET_TYPE_GSM_ONLY = 1, /* GSM only */ + PREF_NET_TYPE_WCDMA = 2, /* WCDMA */ + PREF_NET_TYPE_GSM_WCDMA_AUTO = 3, /* GSM/WCDMA (auto mode, according to PRL) */ + PREF_NET_TYPE_CDMA_EVDO_AUTO = 4, /* CDMA and EvDo (auto mode, according to PRL) */ + PREF_NET_TYPE_CDMA_ONLY = 5, /* CDMA only */ + PREF_NET_TYPE_EVDO_ONLY = 6, /* EvDo only */ + PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO = 7, /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) */ + PREF_NET_TYPE_LTE_CDMA_EVDO = 8, /* LTE, CDMA and EvDo */ + PREF_NET_TYPE_LTE_GSM_WCDMA = 9, /* LTE, GSM/WCDMA */ + PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA = 10, /* LTE, CDMA, EvDo, GSM/WCDMA */ + PREF_NET_TYPE_LTE_ONLY = 11 /* LTE only */ +} RIL_PreferredNetworkType; + +/* Source for cdma subscription */ +typedef enum { + CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM = 0, + CDMA_SUBSCRIPTION_SOURCE_NV = 1 +} RIL_CdmaSubscriptionSource; + +/* User-to-User signaling Info activation types derived from 3GPP 23.087 v8.0 */ +typedef enum { + RIL_UUS_TYPE1_IMPLICIT = 0, + RIL_UUS_TYPE1_REQUIRED = 1, + RIL_UUS_TYPE1_NOT_REQUIRED = 2, + RIL_UUS_TYPE2_REQUIRED = 3, + RIL_UUS_TYPE2_NOT_REQUIRED = 4, + RIL_UUS_TYPE3_REQUIRED = 5, + RIL_UUS_TYPE3_NOT_REQUIRED = 6 +} RIL_UUS_Type; + +/* User-to-User Signaling Information data coding schemes. Possible values for + * Octet 3 (Protocol Discriminator field) in the UUIE. The values have been + * specified in section 10.5.4.25 of 3GPP TS 24.008 */ +typedef enum { + RIL_UUS_DCS_USP = 0, /* User specified protocol */ + RIL_UUS_DCS_OSIHLP = 1, /* OSI higher layer protocol */ + RIL_UUS_DCS_X244 = 2, /* X.244 */ + RIL_UUS_DCS_RMCF = 3, /* Reserved for system mangement + convergence function */ + RIL_UUS_DCS_IA5c = 4 /* IA5 characters */ +} RIL_UUS_DCS; + +/* User-to-User Signaling Information defined in 3GPP 23.087 v8.0 + * This data is passed in RIL_ExtensionRecord and rec contains this + * structure when type is RIL_UUS_INFO_EXT_REC */ +typedef struct { + RIL_UUS_Type uusType; /* UUS Type */ + RIL_UUS_DCS uusDcs; /* UUS Data Coding Scheme */ + int uusLength; /* Length of UUS Data */ + char * uusData; /* UUS Data */ +} RIL_UUS_Info; + +/* CDMA Signal Information Record as defined in C.S0005 section 3.7.5.5 */ +typedef struct { + char isPresent; /* non-zero if signal information record is present */ + char signalType; /* as defined 3.7.5.5-1 */ + char alertPitch; /* as defined 3.7.5.5-2 */ + char signal; /* as defined 3.7.5.5-3, 3.7.5.5-4 or 3.7.5.5-5 */ +} RIL_CDMA_SignalInfoRecord; + +typedef struct { + RIL_CallState state; + int index; /* Connection Index for use with, eg, AT+CHLD */ + int toa; /* type of address, eg 145 = intl */ + char isMpty; /* nonzero if is mpty call */ + char isMT; /* nonzero if call is mobile terminated */ + char als; /* ALS line indicator if available + (0 = line 1) */ + char isVoice; /* nonzero if this is is a voice call */ + char isVoicePrivacy; /* nonzero if CDMA voice privacy mode is active */ + char * number; /* Remote party number */ + int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone */ + char * name; /* Remote party name */ + int namePresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone */ + RIL_UUS_Info * uusInfo; /* NULL or Pointer to User-User Signaling Information */ +} RIL_Call; + +/* Deprecated, use RIL_Data_Call_Response_v6 */ +typedef struct { + int cid; /* Context ID, uniquely identifies this call */ + int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ + char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. + For example, "IP", "IPV6", "IPV4V6", or "PPP". */ + char * apn; /* ignored */ + char * address; /* An address, e.g., "192.0.1.3" or "2001:db8::1". */ +} RIL_Data_Call_Response_v4; + +/* + * Returned by RIL_REQUEST_SETUP_DATA_CALL, RIL_REQUEST_DATA_CALL_LIST + * and RIL_UNSOL_DATA_CALL_LIST_CHANGED, on error status != 0. + */ +typedef struct { + int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ +#ifndef HCRADIO + int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry + back-off timer value RIL wants to override the one + pre-configured in FW. + The unit is miliseconds. + The value < 0 means no value is suggested. + The value 0 means retry should be done ASAP. + The value of INT_MAX(0x7fffffff) means no retry. */ +#endif + int cid; /* Context ID, uniquely identifies this call */ + int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ + char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. + For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is + PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported + such as "IP" or "IPV6" */ + char * ifname; /* The network interface name */ + char * addresses; /* A space-delimited list of addresses with optional "/" prefix length, + e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". + May not be empty, typically 1 IPv4 or 1 IPv6 or + one of each. If the prefix length is absent the addresses + are assumed to be point to point with IPv4 having a prefix + length of 32 and IPv6 128. */ + char * dnses; /* A space-delimited list of DNS server addresses, + e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". + May be empty. */ + char * gateways; /* A space-delimited list of default gateway addresses, + e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". + May be empty in which case the addresses represent point + to point connections. */ +} RIL_Data_Call_Response_v6; + +typedef struct { + int messageRef; /* TP-Message-Reference for GSM, + and BearerData MessageId for CDMA + (See 3GPP2 C.S0015-B, v2.0, table 4.5-1). */ + char *ackPDU; /* or NULL if n/a */ + int errorCode; /* See 3GPP 27.005, 3.2.5 for GSM/UMTS, + 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, + -1 if unknown or not applicable*/ +} RIL_SMS_Response; + +/** Used by RIL_REQUEST_WRITE_SMS_TO_SIM */ +typedef struct { + int status; /* Status of message. See TS 27.005 3.1, "": */ + /* 0 = "REC UNREAD" */ + /* 1 = "REC READ" */ + /* 2 = "STO UNSENT" */ + /* 3 = "STO SENT" */ + char * pdu; /* PDU of message to write, as an ASCII hex string less the SMSC address, + the TP-layer length is "strlen(pdu)/2". */ + char * smsc; /* SMSC address in GSM BCD format prefixed by a length byte + (as expected by TS 27.005) or NULL for default SMSC */ +} RIL_SMS_WriteArgs; + +/** Used by RIL_REQUEST_DIAL */ +typedef struct { + char * address; + int clir; + /* (same as 'n' paremeter in TS 27.007 7.7 "+CLIR" + * clir == 0 on "use subscription default value" + * clir == 1 on "CLIR invocation" (restrict CLI presentation) + * clir == 2 on "CLIR suppression" (allow CLI presentation) + */ + RIL_UUS_Info * uusInfo; /* NULL or Pointer to User-User Signaling Information */ +} RIL_Dial; + +typedef struct { + int command; /* one of the commands listed for TS 27.007 +CRSM*/ + int fileid; /* EF id */ + char *path; /* "pathid" from TS 27.007 +CRSM command. + Path is in hex asciii format eg "7f205f70" + Path must always be provided. + */ + int p1; + int p2; + int p3; + char *data; /* May be NULL*/ + char *pin2; /* May be NULL*/ +} RIL_SIM_IO_v5; + +typedef struct { + int command; /* one of the commands listed for TS 27.007 +CRSM*/ + int fileid; /* EF id */ + char *path; /* "pathid" from TS 27.007 +CRSM command. + Path is in hex asciii format eg "7f205f70" + Path must always be provided. + */ + int p1; + int p2; + int p3; + char *data; /* May be NULL*/ + char *pin2; /* May be NULL*/ + char *aidPtr; /* AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. */ +} RIL_SIM_IO_v6; + +typedef struct { + int sw1; + int sw2; + char *simResponse; /* In hex string format ([a-fA-F0-9]*). */ +} RIL_SIM_IO_Response; + +/* See also com.android.internal.telephony.gsm.CallForwardInfo */ + +typedef struct { + int status; /* + * For RIL_REQUEST_QUERY_CALL_FORWARD_STATUS + * status 1 = active, 0 = not active + * + * For RIL_REQUEST_SET_CALL_FORWARD: + * status is: + * 0 = disable + * 1 = enable + * 2 = interrogate + * 3 = registeration + * 4 = erasure + */ + + int reason; /* from TS 27.007 7.11 "reason" */ + int serviceClass;/* From 27.007 +CCFC/+CLCK "class" + See table for Android mapping from + MMI service code + 0 means user doesn't input class */ + int toa; /* "type" from TS 27.007 7.11 */ + char * number; /* "number" from TS 27.007 7.11. May be NULL */ + int timeSeconds; /* for CF no reply only */ +}RIL_CallForwardInfo; + +typedef struct { + char * cid; /* Combination of LAC and Cell Id in 32 bits in GSM. + * Upper 16 bits is LAC and lower 16 bits + * is CID (as described in TS 27.005) + * Primary Scrambling Code (as described in TS 25.331) + * in 9 bits in UMTS + * Valid values are hexadecimal 0x0000 - 0xffffffff. + */ + int rssi; /* Received RSSI in GSM, + * Level index of CPICH Received Signal Code Power in UMTS + */ +} RIL_NeighboringCell; + +/* See RIL_REQUEST_LAST_CALL_FAIL_CAUSE */ +typedef enum { + CALL_FAIL_UNOBTAINABLE_NUMBER = 1, + CALL_FAIL_NORMAL = 16, + CALL_FAIL_BUSY = 17, + CALL_FAIL_CONGESTION = 34, + CALL_FAIL_ACM_LIMIT_EXCEEDED = 68, + CALL_FAIL_CALL_BARRED = 240, + CALL_FAIL_FDN_BLOCKED = 241, + CALL_FAIL_IMSI_UNKNOWN_IN_VLR = 242, + CALL_FAIL_IMEI_NOT_ACCEPTED = 243, + CALL_FAIL_CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000, + CALL_FAIL_CDMA_DROP = 1001, + CALL_FAIL_CDMA_INTERCEPT = 1002, + CALL_FAIL_CDMA_REORDER = 1003, + CALL_FAIL_CDMA_SO_REJECT = 1004, + CALL_FAIL_CDMA_RETRY_ORDER = 1005, + CALL_FAIL_CDMA_ACCESS_FAILURE = 1006, + CALL_FAIL_CDMA_PREEMPTED = 1007, + CALL_FAIL_CDMA_NOT_EMERGENCY = 1008, /* For non-emergency number dialed + during emergency callback mode */ + CALL_FAIL_CDMA_ACCESS_BLOCKED = 1009, /* CDMA network access probes blocked */ + CALL_FAIL_ERROR_UNSPECIFIED = 0xffff +} RIL_LastCallFailCause; + +/* See RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE */ +typedef enum { + PDP_FAIL_NONE = 0, /* No error, connection ok */ + + /* an integer cause code defined in TS 24.008 + section 6.1.3.1.3 or TS 24.301 Release 8+ Annex B. + If the implementation does not have access to the exact cause codes, + then it should return one of the following values, + as the UI layer needs to distinguish these + cases for error notification and potential retries. */ + PDP_FAIL_OPERATOR_BARRED = 0x08, /* no retry */ + PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A, + PDP_FAIL_MISSING_UKNOWN_APN = 0x1B, /* no retry */ + PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C, /* no retry */ + PDP_FAIL_USER_AUTHENTICATION = 0x1D, /* no retry */ + PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E, /* no retry */ + PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F, + PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20, /* no retry */ + PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21, /* no retry */ + PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22, + PDP_FAIL_NSAPI_IN_USE = 0x23, /* no retry */ + PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32, /* no retry */ + PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33, /* no retry */ + PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34, + PDP_FAIL_PROTOCOL_ERRORS = 0x6F, /* no retry */ + + /* Not mentioned in the specification */ + PDP_FAIL_VOICE_REGISTRATION_FAIL = -1, + PDP_FAIL_DATA_REGISTRATION_FAIL = -2, + + /* reasons for data call drop - network/modem disconnect */ + PDP_FAIL_SIGNAL_LOST = -3, /* no retry */ + PDP_FAIL_PREF_RADIO_TECH_CHANGED = -4,/* preferred technology has changed, should retry + with parameters appropriate for new technology */ + PDP_FAIL_RADIO_POWER_OFF = -5, /* data call was disconnected because radio was resetting, + powered off - no retry */ + PDP_FAIL_TETHERED_CALL_ACTIVE = -6, /* data call was disconnected by modem because tethered + mode was up on same APN/data profile - no retry until + tethered call is off */ + + PDP_FAIL_ERROR_UNSPECIFIED = 0xffff, /* retry silently */ +} RIL_DataCallFailCause; + +/* See RIL_REQUEST_SETUP_DATA_CALL */ +typedef enum { + RIL_DATA_PROFILE_DEFAULT = 0, + RIL_DATA_PROFILE_TETHERED = 1, + RIL_DATA_PROFILE_OEM_BASE = 1000 /* Start of OEM-specific profiles */ +} RIL_DataProfile; + +/* Used by RIL_UNSOL_SUPP_SVC_NOTIFICATION */ +typedef struct { + int notificationType; /* + * 0 = MO intermediate result code + * 1 = MT unsolicited result code + */ + int code; /* See 27.007 7.17 + "code1" for MO + "code2" for MT. */ + int index; /* CUG index. See 27.007 7.17. */ + int type; /* "type" from 27.007 7.17 (MT only). */ + char * number; /* "number" from 27.007 7.17 + (MT only, may be NULL). */ +} RIL_SuppSvcNotification; + +#define RIL_CARD_MAX_APPS 8 + +typedef enum { + RIL_CARDSTATE_ABSENT = 0, + RIL_CARDSTATE_PRESENT = 1, + RIL_CARDSTATE_ERROR = 2 +} RIL_CardState; + +typedef enum { + RIL_PERSOSUBSTATE_UNKNOWN = 0, /* initial state */ + RIL_PERSOSUBSTATE_IN_PROGRESS = 1, /* in between each lock transition */ + RIL_PERSOSUBSTATE_READY = 2, /* when either SIM or RUIM Perso is finished + since each app can only have 1 active perso + involved */ + RIL_PERSOSUBSTATE_SIM_NETWORK = 3, + RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET = 4, + RIL_PERSOSUBSTATE_SIM_CORPORATE = 5, + RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER = 6, + RIL_PERSOSUBSTATE_SIM_SIM = 7, + RIL_PERSOSUBSTATE_SIM_NETWORK_PUK = 8, /* The corresponding perso lock is blocked */ + RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK = 9, + RIL_PERSOSUBSTATE_SIM_CORPORATE_PUK = 10, + RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK = 11, + RIL_PERSOSUBSTATE_SIM_SIM_PUK = 12, + RIL_PERSOSUBSTATE_RUIM_NETWORK1 = 13, + RIL_PERSOSUBSTATE_RUIM_NETWORK2 = 14, + RIL_PERSOSUBSTATE_RUIM_HRPD = 15, + RIL_PERSOSUBSTATE_RUIM_CORPORATE = 16, + RIL_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER = 17, + RIL_PERSOSUBSTATE_RUIM_RUIM = 18, + RIL_PERSOSUBSTATE_RUIM_NETWORK1_PUK = 19, /* The corresponding perso lock is blocked */ + RIL_PERSOSUBSTATE_RUIM_NETWORK2_PUK = 20, + RIL_PERSOSUBSTATE_RUIM_HRPD_PUK = 21, + RIL_PERSOSUBSTATE_RUIM_CORPORATE_PUK = 22, + RIL_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK = 23, + RIL_PERSOSUBSTATE_RUIM_RUIM_PUK = 24 +} RIL_PersoSubstate; + +typedef enum { + RIL_APPSTATE_UNKNOWN = 0, + RIL_APPSTATE_DETECTED = 1, + RIL_APPSTATE_PIN = 2, /* If PIN1 or UPin is required */ + RIL_APPSTATE_PUK = 3, /* If PUK1 or Puk for UPin is required */ + RIL_APPSTATE_SUBSCRIPTION_PERSO = 4, /* perso_substate should be look at + when app_state is assigned to this value */ + RIL_APPSTATE_READY = 5 +} RIL_AppState; + +typedef enum { + RIL_PINSTATE_UNKNOWN = 0, + RIL_PINSTATE_ENABLED_NOT_VERIFIED = 1, + RIL_PINSTATE_ENABLED_VERIFIED = 2, + RIL_PINSTATE_DISABLED = 3, + RIL_PINSTATE_ENABLED_BLOCKED = 4, + RIL_PINSTATE_ENABLED_PERM_BLOCKED = 5 +} RIL_PinState; + +typedef enum { + RIL_APPTYPE_UNKNOWN = 0, + RIL_APPTYPE_SIM = 1, + RIL_APPTYPE_USIM = 2, + RIL_APPTYPE_RUIM = 3, + RIL_APPTYPE_CSIM = 4, + RIL_APPTYPE_ISIM = 5 +} RIL_AppType; + +typedef struct +{ + RIL_AppType app_type; + RIL_AppState app_state; + RIL_PersoSubstate perso_substate; /* applicable only if app_state == + RIL_APPSTATE_SUBSCRIPTION_PERSO */ + char *aid_ptr; /* null terminated string, e.g., from 0xA0, 0x00 -> 0x41, + 0x30, 0x30, 0x30 */ + char *app_label_ptr; /* null terminated string */ + int pin1_replaced; /* applicable to USIM, CSIM & ISIM */ + RIL_PinState pin1; + RIL_PinState pin2; + int foo1; /* Samsung */ + int foo2; /* Samsung */ + int foo3; /* Samsung */ + int foo4; /* Samsung */ + int foo5; /* Samsung */ +} RIL_AppStatus; + +/* Deprecated, use RIL_CardStatus_v6 */ +typedef struct +{ + RIL_CardState card_state; + RIL_PinState universal_pin_state; /* applicable to USIM and CSIM: RIL_PINSTATE_xxx */ + int gsm_umts_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ + int cdma_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ + int num_applications; /* value <= RIL_CARD_MAX_APPS */ + RIL_AppStatus applications[RIL_CARD_MAX_APPS]; +} RIL_CardStatus_v5; + +typedef struct +{ + RIL_CardState card_state; + RIL_PinState universal_pin_state; /* applicable to USIM and CSIM: RIL_PINSTATE_xxx */ + int gsm_umts_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ + int cdma_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ + int ims_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ + int num_applications; /* value <= RIL_CARD_MAX_APPS */ + RIL_AppStatus applications[RIL_CARD_MAX_APPS]; +} RIL_CardStatus_v6; + +/** The result of a SIM refresh, returned in data[0] of RIL_UNSOL_SIM_REFRESH + * or as part of RIL_SimRefreshResponse_v7 + */ +typedef enum { + /* A file on SIM has been updated. data[1] contains the EFID. */ + SIM_FILE_UPDATE = 0, + /* SIM initialized. All files should be re-read. */ + SIM_INIT = 1, + /* SIM reset. SIM power required, SIM may be locked and all files should be re-read. */ + SIM_RESET = 2 +} RIL_SimRefreshResult; + +typedef struct { + RIL_SimRefreshResult result; + int ef_id; /* is the EFID of the updated file if the result is */ + /* SIM_FILE_UPDATE or 0 for any other result. */ + char * aid; /* is AID(application ID) of the card application */ + /* See ETSI 102.221 8.1 and 101.220 4 */ + /* For SIM_FILE_UPDATE result it can be set to AID of */ + /* application in which updated EF resides or it can be */ + /* NULL if EF is outside of an application. */ + /* For SIM_INIT result this field is set to AID of */ + /* application that caused REFRESH */ + /* For SIM_RESET result it is NULL. */ +} RIL_SimRefreshResponse_v7; + +/* Deprecated, use RIL_CDMA_CallWaiting_v6 */ +typedef struct { + char * number; /* Remote party number */ + int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown */ + char * name; /* Remote party name */ + RIL_CDMA_SignalInfoRecord signalInfoRecord; +} RIL_CDMA_CallWaiting_v5; + +typedef struct { + char * number; /* Remote party number */ + int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown */ + char * name; /* Remote party name */ + RIL_CDMA_SignalInfoRecord signalInfoRecord; + /* Number type/Number plan required to support International Call Waiting */ + int number_type; /* 0=Unknown, 1=International, 2=National, + 3=Network specific, 4=subscriber */ + int number_plan; /* 0=Unknown, 1=ISDN, 3=Data, 4=Telex, 8=Nat'l, 9=Private */ +} RIL_CDMA_CallWaiting_v6; + +/** + * Which types of Cell Broadcast Message (CBM) are to be received by the ME + * + * uFromServiceID - uToServiceID defines a range of CBM message identifiers + * whose value is 0x0000 - 0xFFFF as defined in TS 23.041 9.4.1.2.2 for GMS + * and 9.4.4.2.2 for UMTS. All other values can be treated as empty + * CBM message ID. + * + * uFromCodeScheme - uToCodeScheme defines a range of CBM data coding schemes + * whose value is 0x00 - 0xFF as defined in TS 23.041 9.4.1.2.3 for GMS + * and 9.4.4.2.3 for UMTS. + * All other values can be treated as empty CBM data coding scheme. + * + * selected 0 means message types specified in + * and are not accepted, while 1 means accepted. + * + * Used by RIL_REQUEST_GSM_GET_BROADCAST_CONFIG and + * RIL_REQUEST_GSM_SET_BROADCAST_CONFIG. + */ +typedef struct { + int fromServiceId; + int toServiceId; + int fromCodeScheme; + int toCodeScheme; + unsigned char selected; +} RIL_GSM_BroadcastSmsConfigInfo; + +/* No restriction at all including voice/SMS/USSD/SS/AV64 and packet data. */ +#define RIL_RESTRICTED_STATE_NONE 0x00 +/* Block emergency call due to restriction. But allow all normal voice/SMS/USSD/SS/AV64. */ +#define RIL_RESTRICTED_STATE_CS_EMERGENCY 0x01 +/* Block all normal voice/SMS/USSD/SS/AV64 due to restriction. Only Emergency call allowed. */ +#define RIL_RESTRICTED_STATE_CS_NORMAL 0x02 +/* Block all voice/SMS/USSD/SS/AV64 including emergency call due to restriction.*/ +#define RIL_RESTRICTED_STATE_CS_ALL 0x04 +/* Block packet data access due to restriction. */ +#define RIL_RESTRICTED_STATE_PS_ALL 0x10 + +/* The status for an OTASP/OTAPA session */ +typedef enum { + CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED, + CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED, + CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED, + CDMA_OTA_PROVISION_STATUS_SSD_UPDATED, + CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED, + CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED, + CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED, + CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED, + CDMA_OTA_PROVISION_STATUS_COMMITTED, + CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED, + CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED, + CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED +} RIL_CDMA_OTA_ProvisionStatus; + +typedef struct { + int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ + int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ +} RIL_GW_SignalStrength; + +typedef struct { + int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ + int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ +} RIL_SignalStrengthWcdma; + +typedef struct { + int dbm; /* Valid values are positive integers. This value is the actual RSSI value + * multiplied by -1. Example: If the actual RSSI is -75, then this response + * value will be 75. + */ + int ecio; /* Valid values are positive integers. This value is the actual Ec/Io multiplied + * by -10. Example: If the actual Ec/Io is -12.5 dB, then this response value + * will be 125. + */ +} RIL_CDMA_SignalStrength; + + +typedef struct { + int dbm; /* Valid values are positive integers. This value is the actual RSSI value + * multiplied by -1. Example: If the actual RSSI is -75, then this response + * value will be 75. + */ + int ecio; /* Valid values are positive integers. This value is the actual Ec/Io multiplied + * by -10. Example: If the actual Ec/Io is -12.5 dB, then this response value + * will be 125. + */ + int signalNoiseRatio; /* Valid values are 0-8. 8 is the highest signal to noise ratio. */ +} RIL_EVDO_SignalStrength; + +typedef struct { + int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ + int rsrp; /* The current Reference Signal Receive Power in dBm multipled by -1. + * Range: 44 to 140 dBm + * INT_MAX: 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.133 9.1.4 */ + int rsrq; /* The current Reference Signal Receive Quality in dB multiplied by -1. + * Range: 20 to 3 dB. + * INT_MAX: 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.133 9.1.7 */ + int rssnr; /* The current reference signal signal-to-noise ratio in 0.1 dB units. + * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB). + * INT_MAX : 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.101 8.1.1 */ + int cqi; /* The current Channel Quality Indicator. + * Range: 0 to 15. + * INT_MAX : 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */ +} RIL_LTE_SignalStrength; + +typedef struct { + int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ + int rsrp; /* The current Reference Signal Receive Power in dBm multipled by -1. + * Range: 44 to 140 dBm + * INT_MAX: 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.133 9.1.4 */ + int rsrq; /* The current Reference Signal Receive Quality in dB multiplied by -1. + * Range: 20 to 3 dB. + * INT_MAX: 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.133 9.1.7 */ + int rssnr; /* The current reference signal signal-to-noise ratio in 0.1 dB units. + * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB). + * INT_MAX : 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.101 8.1.1 */ + int cqi; /* The current Channel Quality Indicator. + * Range: 0 to 15. + * INT_MAX : 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */ + int timingAdvance; /* timing advance in micro seconds for a one way trip from cell to device. + * Approximate distance can be calculated using 300m/us * timingAdvance. + * Range: 0 to 0x7FFFFFFE + * INT_MAX : 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP 36.321 section 6.1.3.5 + * also: http://www.cellular-planningoptimization.com/2010/02/timing-advance-with-calculation.html */ +} RIL_LTE_SignalStrength_v8; + +/* Deprecated, use RIL_SignalStrength_v6 */ +typedef struct { + RIL_GW_SignalStrength GW_SignalStrength; + RIL_CDMA_SignalStrength CDMA_SignalStrength; + RIL_EVDO_SignalStrength EVDO_SignalStrength; +} RIL_SignalStrength_v5; + +typedef struct { + RIL_GW_SignalStrength GW_SignalStrength; + RIL_CDMA_SignalStrength CDMA_SignalStrength; + RIL_EVDO_SignalStrength EVDO_SignalStrength; + RIL_LTE_SignalStrength LTE_SignalStrength; +} RIL_SignalStrength_v6; + +typedef struct { + RIL_GW_SignalStrength GW_SignalStrength; + RIL_CDMA_SignalStrength CDMA_SignalStrength; + RIL_EVDO_SignalStrength EVDO_SignalStrength; + RIL_LTE_SignalStrength_v8 LTE_SignalStrength; +} RIL_SignalStrength_v8; + +/** RIL_CellIdentityGsm */ +typedef struct { + int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ + int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ + int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ + int cid; /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown */ +} RIL_CellIdentityGsm; + +/** RIL_CellIdentityWcdma */ +typedef struct { + int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ + int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ + int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ + int cid; /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */ + int psc; /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511, INT_MAX if unknown */ +} RIL_CellIdentityWcdma; + +/** RIL_CellIdentityCdma */ +typedef struct { + int networkId; /* Network Id 0..65535, INT_MAX if unknown */ + int systemId; /* CDMA System Id 0..32767, INT_MAX if unknown */ + int basestationId; /* Base Station Id 0..65535, INT_MAX if unknown */ + int longitude; /* Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. + * It is represented in units of 0.25 seconds and ranges from -2592000 + * to 2592000, both values inclusive (corresponding to a range of -180 + * to +180 degrees). INT_MAX if unknown */ + + int latitude; /* Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. + * It is represented in units of 0.25 seconds and ranges from -1296000 + * to 1296000, both values inclusive (corresponding to a range of -90 + * to +90 degrees). INT_MAX if unknown */ +} RIL_CellIdentityCdma; + +/** RIL_CellIdentityLte */ +typedef struct { + int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ + int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ + int ci; /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */ + int pci; /* physical cell id 0..503, INT_MAX if unknown */ + int tac; /* 16-bit tracking area code, INT_MAX if unknown */ +} RIL_CellIdentityLte; + +/** RIL_CellInfoGsm */ +typedef struct { + RIL_CellIdentityGsm cellIdentityGsm; + RIL_GW_SignalStrength signalStrengthGsm; +} RIL_CellInfoGsm; + +/** RIL_CellInfoWcdma */ +typedef struct { + RIL_CellIdentityWcdma cellIdentityWcdma; + RIL_SignalStrengthWcdma signalStrengthWcdma; +} RIL_CellInfoWcdma; + +/** RIL_CellInfoCdma */ +typedef struct { + RIL_CellIdentityCdma cellIdentityCdma; + RIL_CDMA_SignalStrength signalStrengthCdma; + RIL_EVDO_SignalStrength signalStrengthEvdo; +} RIL_CellInfoCdma; + +/** RIL_CellInfoLte */ +typedef struct { + RIL_CellIdentityLte cellIdentityLte; + RIL_LTE_SignalStrength_v8 signalStrengthLte; +} RIL_CellInfoLte; + +// Must be the same as CellInfo.TYPE_XXX +typedef enum { + RIL_CELL_INFO_TYPE_GSM = 1, + RIL_CELL_INFO_TYPE_CDMA = 2, + RIL_CELL_INFO_TYPE_LTE = 3, + RIL_CELL_INFO_TYPE_WCDMA = 4, +} RIL_CellInfoType; + +// Must be the same as CellInfo.TIMESTAMP_TYPE_XXX +typedef enum { + RIL_TIMESTAMP_TYPE_UNKNOWN = 0, + RIL_TIMESTAMP_TYPE_ANTENNA = 1, + RIL_TIMESTAMP_TYPE_MODEM = 2, + RIL_TIMESTAMP_TYPE_OEM_RIL = 3, + RIL_TIMESTAMP_TYPE_JAVA_RIL = 4, +} RIL_TimeStampType; + +typedef struct { + RIL_CellInfoType cellInfoType; /* cell type for selecting from union CellInfo */ + int registered; /* !0 if this cell is registered 0 if not registered */ + RIL_TimeStampType timeStampType; /* type of time stamp represented by timeStamp */ + uint64_t timeStamp; /* Time in nanos as returned by ril_nano_time */ + union { + RIL_CellInfoGsm gsm; + RIL_CellInfoCdma cdma; + RIL_CellInfoLte lte; + RIL_CellInfoWcdma wcdma; + } CellInfo; +} RIL_CellInfo; + +/* Names of the CDMA info records (C.S0005 section 3.7.5) */ +typedef enum { + RIL_CDMA_DISPLAY_INFO_REC, + RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC, + RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC, + RIL_CDMA_CONNECTED_NUMBER_INFO_REC, + RIL_CDMA_SIGNAL_INFO_REC, + RIL_CDMA_REDIRECTING_NUMBER_INFO_REC, + RIL_CDMA_LINE_CONTROL_INFO_REC, + RIL_CDMA_EXTENDED_DISPLAY_INFO_REC, + RIL_CDMA_T53_CLIR_INFO_REC, + RIL_CDMA_T53_RELEASE_INFO_REC, + RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC +} RIL_CDMA_InfoRecName; + +/* Display Info Rec as defined in C.S0005 section 3.7.5.1 + Extended Display Info Rec as defined in C.S0005 section 3.7.5.16 + Note: the Extended Display info rec contains multiple records of the + form: display_tag, display_len, and display_len occurrences of the + chari field if the display_tag is not 10000000 or 10000001. + To save space, the records are stored consecutively in a byte buffer. + The display_tag, display_len and chari fields are all 1 byte. +*/ + +typedef struct { + char alpha_len; + char alpha_buf[CDMA_ALPHA_INFO_BUFFER_LENGTH]; +} RIL_CDMA_DisplayInfoRecord; + +/* Called Party Number Info Rec as defined in C.S0005 section 3.7.5.2 + Calling Party Number Info Rec as defined in C.S0005 section 3.7.5.3 + Connected Number Info Rec as defined in C.S0005 section 3.7.5.4 +*/ + +typedef struct { + char len; + char buf[CDMA_NUMBER_INFO_BUFFER_LENGTH]; + char number_type; + char number_plan; + char pi; + char si; +} RIL_CDMA_NumberInfoRecord; + +/* Redirecting Number Information Record as defined in C.S0005 section 3.7.5.11 */ +typedef enum { + RIL_REDIRECTING_REASON_UNKNOWN = 0, + RIL_REDIRECTING_REASON_CALL_FORWARDING_BUSY = 1, + RIL_REDIRECTING_REASON_CALL_FORWARDING_NO_REPLY = 2, + RIL_REDIRECTING_REASON_CALLED_DTE_OUT_OF_ORDER = 9, + RIL_REDIRECTING_REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10, + RIL_REDIRECTING_REASON_CALL_FORWARDING_UNCONDITIONAL = 15, + RIL_REDIRECTING_REASON_RESERVED +} RIL_CDMA_RedirectingReason; + +typedef struct { + RIL_CDMA_NumberInfoRecord redirectingNumber; + /* redirectingReason is set to RIL_REDIRECTING_REASON_UNKNOWN if not included */ + RIL_CDMA_RedirectingReason redirectingReason; +} RIL_CDMA_RedirectingNumberInfoRecord; + +/* Line Control Information Record as defined in C.S0005 section 3.7.5.15 */ +typedef struct { + char lineCtrlPolarityIncluded; + char lineCtrlToggle; + char lineCtrlReverse; + char lineCtrlPowerDenial; +} RIL_CDMA_LineControlInfoRecord; + +/* T53 CLIR Information Record */ +typedef struct { + char cause; +} RIL_CDMA_T53_CLIRInfoRecord; + +/* T53 Audio Control Information Record */ +typedef struct { + char upLink; + char downLink; +} RIL_CDMA_T53_AudioControlInfoRecord; + +typedef struct { + + RIL_CDMA_InfoRecName name; + + union { + /* Display and Extended Display Info Rec */ + RIL_CDMA_DisplayInfoRecord display; + + /* Called Party Number, Calling Party Number, Connected Number Info Rec */ + RIL_CDMA_NumberInfoRecord number; + + /* Signal Info Rec */ + RIL_CDMA_SignalInfoRecord signal; + + /* Redirecting Number Info Rec */ + RIL_CDMA_RedirectingNumberInfoRecord redir; + + /* Line Control Info Rec */ + RIL_CDMA_LineControlInfoRecord lineCtrl; + + /* T53 CLIR Info Rec */ + RIL_CDMA_T53_CLIRInfoRecord clir; + + /* T53 Audio Control Info Rec */ + RIL_CDMA_T53_AudioControlInfoRecord audioCtrl; + } rec; +} RIL_CDMA_InformationRecord; + +#define RIL_CDMA_MAX_NUMBER_OF_INFO_RECS 10 + +typedef struct { + char numberOfInfoRecs; + RIL_CDMA_InformationRecord infoRec[RIL_CDMA_MAX_NUMBER_OF_INFO_RECS]; +} RIL_CDMA_InformationRecords; + +/** + * RIL_REQUEST_GET_SIM_STATUS + * + * Requests status of the SIM interface and the SIM card + * + * "data" is NULL + * + * "response" is const RIL_CardStatus_v6 * + * + * Valid errors: + * Must never fail + */ +#define RIL_REQUEST_GET_SIM_STATUS 1 + +/** + * RIL_REQUEST_ENTER_SIM_PIN + * + * Supplies SIM PIN. Only called if RIL_CardStatus has RIL_APPSTATE_PIN state + * + * "data" is const char ** + * ((const char **)data)[0] is PIN value + * ((const char **)data)[1] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * PASSWORD_INCORRECT + */ + +#define RIL_REQUEST_ENTER_SIM_PIN 2 + + +/** + * RIL_REQUEST_ENTER_SIM_PUK + * + * Supplies SIM PUK and new PIN. + * + * "data" is const char ** + * ((const char **)data)[0] is PUK value + * ((const char **)data)[1] is new PIN value + * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * PASSWORD_INCORRECT + * (PUK is invalid) + */ + +#define RIL_REQUEST_ENTER_SIM_PUK 3 + +/** + * RIL_REQUEST_ENTER_SIM_PIN2 + * + * Supplies SIM PIN2. Only called following operation where SIM_PIN2 was + * returned as a a failure from a previous operation. + * + * "data" is const char ** + * ((const char **)data)[0] is PIN2 value + * ((const char **)data)[1] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * PASSWORD_INCORRECT + */ + +#define RIL_REQUEST_ENTER_SIM_PIN2 4 + +/** + * RIL_REQUEST_ENTER_SIM_PUK2 + * + * Supplies SIM PUK2 and new PIN2. + * + * "data" is const char ** + * ((const char **)data)[0] is PUK2 value + * ((const char **)data)[1] is new PIN2 value + * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * PASSWORD_INCORRECT + * (PUK2 is invalid) + */ + +#define RIL_REQUEST_ENTER_SIM_PUK2 5 + +/** + * RIL_REQUEST_CHANGE_SIM_PIN + * + * Supplies old SIM PIN and new PIN. + * + * "data" is const char ** + * ((const char **)data)[0] is old PIN value + * ((const char **)data)[1] is new PIN value + * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * PASSWORD_INCORRECT + * (old PIN is invalid) + * + */ + +#define RIL_REQUEST_CHANGE_SIM_PIN 6 + + +/** + * RIL_REQUEST_CHANGE_SIM_PIN2 + * + * Supplies old SIM PIN2 and new PIN2. + * + * "data" is const char ** + * ((const char **)data)[0] is old PIN2 value + * ((const char **)data)[1] is new PIN2 value + * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * PASSWORD_INCORRECT + * (old PIN2 is invalid) + * + */ + +#define RIL_REQUEST_CHANGE_SIM_PIN2 7 + +/** + * RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION + * + * Requests that network personlization be deactivated + * + * "data" is const char ** + * ((const char **)(data))[0]] is network depersonlization code + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * PASSWORD_INCORRECT + * (code is invalid) + */ + +#define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8 + +/** + * RIL_REQUEST_GET_CURRENT_CALLS + * + * Requests current call list + * + * "data" is NULL + * + * "response" must be a "const RIL_Call **" + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * (request will be made again in a few hundred msec) + */ + +#define RIL_REQUEST_GET_CURRENT_CALLS 9 + + +/** + * RIL_REQUEST_DIAL + * + * Initiate voice call + * + * "data" is const RIL_Dial * + * "response" is NULL + * + * This method is never used for supplementary service codes + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ +#define RIL_REQUEST_DIAL 10 + +/** + * RIL_REQUEST_GET_IMSI + * + * Get the SIM IMSI + * + * Only valid when radio state is "RADIO_STATE_ON" + * + * "data" is const char ** + * ((const char **)data)[0] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * "response" is a const char * containing the IMSI + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_GET_IMSI 11 + +/** + * RIL_REQUEST_HANGUP + * + * Hang up a specific line (like AT+CHLD=1x) + * + * After this HANGUP request returns, RIL should show the connection is NOT + * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. + * + * "data" is an int * + * (int *)data)[0] contains Connection index (value of 'x' in CHLD above) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_HANGUP 12 + +/** + * RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND + * + * Hang up waiting or held (like AT+CHLD=0) + * + * After this HANGUP request returns, RIL should show the connection is NOT + * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13 + +/** + * RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND + * + * Hang up waiting or held (like AT+CHLD=1) + * + * After this HANGUP request returns, RIL should show the connection is NOT + * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14 + +/** + * RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE + * + * Switch waiting or holding call and active call (like AT+CHLD=2) + * + * State transitions should be is follows: + * + * If call 1 is waiting and call 2 is active, then if this re + * + * BEFORE AFTER + * Call 1 Call 2 Call 1 Call 2 + * ACTIVE HOLDING HOLDING ACTIVE + * ACTIVE WAITING HOLDING ACTIVE + * HOLDING WAITING HOLDING ACTIVE + * ACTIVE IDLE HOLDING IDLE + * IDLE IDLE IDLE IDLE + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE 15 +#define RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE 15 + +/** + * RIL_REQUEST_CONFERENCE + * + * Conference holding and active (like AT+CHLD=3) + + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ +#define RIL_REQUEST_CONFERENCE 16 + +/** + * RIL_REQUEST_UDUB + * + * Send UDUB (user determined used busy) to ringing or + * waiting call answer)(RIL_BasicRequest r); + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ +#define RIL_REQUEST_UDUB 17 + +/** + * RIL_REQUEST_LAST_CALL_FAIL_CAUSE + * + * Requests the failure cause code for the most recently terminated call + * + * "data" is NULL + * "response" is a "int *" + * ((int *)response)[0] is RIL_LastCallFailCause. GSM failure reasons are + * mapped to cause codes defined in TS 24.008 Annex H where possible. CDMA + * failure reasons are derived from the possible call failure scenarios + * described in the "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard. + * + * The implementation should return CALL_FAIL_ERROR_UNSPECIFIED for blocked + * MO calls by restricted state (See RIL_UNSOL_RESTRICTED_STATE_CHANGED) + * + * If the implementation does not have access to the exact cause codes, + * then it should return one of the values listed in RIL_LastCallFailCause, + * as the UI layer needs to distinguish these cases for tone generation or + * error notification. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + * See also: RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE + */ +#define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18 + +/** + * RIL_REQUEST_SIGNAL_STRENGTH + * + * Requests current signal strength and associated information + * + * Must succeed if radio is on. + * + * "data" is NULL + * + * "response" is a const RIL_SignalStrength * + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + */ +#define RIL_REQUEST_SIGNAL_STRENGTH 19 + +/** + * RIL_REQUEST_VOICE_REGISTRATION_STATE + * + * Request current registration state + * + * "data" is NULL + * "response" is a "char **" + * ((const char **)response)[0] is registration state 0-6, + * 0 - Not registered, MT is not currently searching + * a new operator to register + * 1 - Registered, home network + * 2 - Not registered, but MT is currently searching + * a new operator to register + * 3 - Registration denied + * 4 - Unknown + * 5 - Registered, roaming + * 10 - Same as 0, but indicates that emergency calls + * are enabled. + * 12 - Same as 2, but indicates that emergency calls + * are enabled. + * 13 - Same as 3, but indicates that emergency calls + * are enabled. + * 14 - Same as 4, but indicates that emergency calls + * are enabled. + * + * ((const char **)response)[1] is LAC if registered on a GSM/WCDMA system or + * NULL if not.Valid LAC are 0x0000 - 0xffff + * ((const char **)response)[2] is CID if registered on a * GSM/WCDMA or + * NULL if not. + * Valid CID are 0x00000000 - 0xffffffff + * In GSM, CID is Cell ID (see TS 27.007) + * in 16 bits + * In UMTS, CID is UMTS Cell Identity + * (see TS 25.331) in 28 bits + * ((const char **)response)[3] indicates the available voice radio technology, + * valid values as defined by RIL_RadioTechnology. + * ((const char **)response)[4] is Base Station ID if registered on a CDMA + * system or NULL if not. Base Station ID in + * decimal format + * ((const char **)response)[5] is Base Station latitude if registered on a + * CDMA system or NULL if not. Base Station + * latitude is a decimal number as specified in + * 3GPP2 C.S0005-A v6.0. It is represented in + * units of 0.25 seconds and ranges from -1296000 + * to 1296000, both values inclusive (corresponding + * to a range of -90 to +90 degrees). + * ((const char **)response)[6] is Base Station longitude if registered on a + * CDMA system or NULL if not. Base Station + * longitude is a decimal number as specified in + * 3GPP2 C.S0005-A v6.0. It is represented in + * units of 0.25 seconds and ranges from -2592000 + * to 2592000, both values inclusive (corresponding + * to a range of -180 to +180 degrees). + * ((const char **)response)[7] is concurrent services support indicator if + * registered on a CDMA system 0-1. + * 0 - Concurrent services not supported, + * 1 - Concurrent services supported + * ((const char **)response)[8] is System ID if registered on a CDMA system or + * NULL if not. Valid System ID are 0 - 32767 + * ((const char **)response)[9] is Network ID if registered on a CDMA system or + * NULL if not. Valid System ID are 0 - 65535 + * ((const char **)response)[10] is the TSB-58 Roaming Indicator if registered + * on a CDMA or EVDO system or NULL if not. Valid values + * are 0-255. + * ((const char **)response)[11] indicates whether the current system is in the + * PRL if registered on a CDMA or EVDO system or NULL if + * not. 0=not in the PRL, 1=in the PRL + * ((const char **)response)[12] is the default Roaming Indicator from the PRL, + * if registered on a CDMA or EVDO system or NULL if not. + * Valid values are 0-255. + * ((const char **)response)[13] if registration state is 3 (Registration + * denied) this is an enumerated reason why + * registration was denied. See 3GPP TS 24.008, + * 10.5.3.6 and Annex G. + * 0 - General + * 1 - Authentication Failure + * 2 - IMSI unknown in HLR + * 3 - Illegal MS + * 4 - Illegal ME + * 5 - PLMN not allowed + * 6 - Location area not allowed + * 7 - Roaming not allowed + * 8 - No Suitable Cells in this Location Area + * 9 - Network failure + * 10 - Persistent location update reject + * 11 - PLMN not allowed + * 12 - Location area not allowed + * 13 - Roaming not allowed in this Location Area + * 15 - No Suitable Cells in this Location Area + * 17 - Network Failure + * 20 - MAC Failure + * 21 - Sync Failure + * 22 - Congestion + * 23 - GSM Authentication unacceptable + * 25 - Not Authorized for this CSG + * 32 - Service option not supported + * 33 - Requested service option not subscribed + * 34 - Service option temporarily out of order + * 38 - Call cannot be identified + * 48-63 - Retry upon entry into a new cell + * 95 - Semantically incorrect message + * 96 - Invalid mandatory information + * 97 - Message type non-existent or not implemented + * 98 - Message not compatible with protocol state + * 99 - Information element non-existent or not implemented + * 100 - Conditional IE error + * 101 - Message not compatible with protocol state + * 111 - Protocol error, unspecified + * ((const char **)response)[14] is the Primary Scrambling Code of the current + * cell as described in TS 25.331, in hexadecimal + * format, or NULL if unknown or not registered + * to a UMTS network. + * + * Please note that registration state 4 ("unknown") is treated + * as "out of service" in the Android telephony system + * + * Registration state 3 can be returned if Location Update Reject + * (with cause 17 - Network Failure) is received repeatedly from the network, + * to facilitate "managed roaming" + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_VOICE_REGISTRATION_STATE 20 + +/** + * RIL_REQUEST_DATA_REGISTRATION_STATE + * + * Request current DATA registration state + * + * "data" is NULL + * "response" is a "char **" + * ((const char **)response)[0] is registration state 0-5 from TS 27.007 10.1.20 AT+CGREG + * ((const char **)response)[1] is LAC if registered or NULL if not + * ((const char **)response)[2] is CID if registered or NULL if not + * ((const char **)response)[3] indicates the available data radio technology, + * valid values as defined by RIL_RadioTechnology. + * ((const char **)response)[4] if registration state is 3 (Registration + * denied) this is an enumerated reason why + * registration was denied. See 3GPP TS 24.008, + * Annex G.6 "Additonal cause codes for GMM". + * 7 == GPRS services not allowed + * 8 == GPRS services and non-GPRS services not allowed + * 9 == MS identity cannot be derived by the network + * 10 == Implicitly detached + * 14 == GPRS services not allowed in this PLMN + * 16 == MSC temporarily not reachable + * 40 == No PDP context activated + * ((const char **)response)[5] The maximum number of simultaneous Data Calls that can be + * established using RIL_REQUEST_SETUP_DATA_CALL. + * + * The values at offsets 6..10 are optional LTE location information in decimal. + * If a value is unknown that value may be NULL. If all values are NULL, + * none need to be present. + * ((const char **)response)[6] is TAC, a 16-bit Tracking Area Code. + * ((const char **)response)[7] is CID, a 0-503 Physical Cell Identifier. + * ((const char **)response)[8] is ECI, a 28-bit E-UTRAN Cell Identifier. + * ((const char **)response)[9] is CSGID, a 27-bit Closed Subscriber Group Identity. + * ((const char **)response)[10] is TADV, a 6-bit timing advance value. + * + * LAC and CID are in hexadecimal format. + * valid LAC are 0x0000 - 0xffff + * valid CID are 0x00000000 - 0x0fffffff + * + * Please note that registration state 4 ("unknown") is treated + * as "out of service" in the Android telephony system + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_DATA_REGISTRATION_STATE 21 + +/** + * RIL_REQUEST_OPERATOR + * + * Request current operator ONS or EONS + * + * "data" is NULL + * "response" is a "const char **" + * ((const char **)response)[0] is long alpha ONS or EONS + * or NULL if unregistered + * + * ((const char **)response)[1] is short alpha ONS or EONS + * or NULL if unregistered + * ((const char **)response)[2] is 5 or 6 digit numeric code (MCC + MNC) + * or NULL if unregistered + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_OPERATOR 22 + +/** + * RIL_REQUEST_RADIO_POWER + * + * Toggle radio on and off (for "airplane" mode) + * If the radio is is turned off/on the radio modem subsystem + * is expected return to an initialized state. For instance, + * any voice and data calls will be terminated and all associated + * lists emptied. + * + * "data" is int * + * ((int *)data)[0] is > 0 for "Radio On" + * ((int *)data)[0] is == 0 for "Radio Off" + * + * "response" is NULL + * + * Turn radio on if "on" > 0 + * Turn radio off if "on" == 0 + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_RADIO_POWER 23 + +/** + * RIL_REQUEST_DTMF + * + * Send a DTMF tone + * + * If the implementation is currently playing a tone requested via + * RIL_REQUEST_DTMF_START, that tone should be cancelled and the new tone + * should be played instead + * + * "data" is a char * containing a single character with one of 12 values: 0-9,*,# + * "response" is NULL + * + * FIXME should this block/mute microphone? + * How does this interact with local DTMF feedback? + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + * See also: RIL_REQUEST_DTMF_STOP, RIL_REQUEST_DTMF_START + * + */ +#define RIL_REQUEST_DTMF 24 + +/** + * RIL_REQUEST_SEND_SMS + * + * Send an SMS message + * + * "data" is const char ** + * ((const char **)data)[0] is SMSC address in GSM BCD format prefixed + * by a length byte (as expected by TS 27.005) or NULL for default SMSC + * ((const char **)data)[1] is SMS in PDU format as an ASCII hex string + * less the SMSC address + * TP-Layer-Length is be "strlen(((const char **)data)[1])/2" + * + * "response" is a const RIL_SMS_Response * + * + * Based on the return error, caller decides to resend if sending sms + * fails. SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) + * and GENERIC_FAILURE means no retry (i.e. error cause is 500) + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SMS_SEND_FAIL_RETRY + * FDN_CHECK_FAILURE + * GENERIC_FAILURE + * + * FIXME how do we specify TP-Message-Reference if we need to resend? + */ +#define RIL_REQUEST_SEND_SMS 25 + + +/** + * RIL_REQUEST_SEND_SMS_EXPECT_MORE + * + * Send an SMS message. Identical to RIL_REQUEST_SEND_SMS, + * except that more messages are expected to be sent soon. If possible, + * keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command) + * + * "data" is const char ** + * ((const char **)data)[0] is SMSC address in GSM BCD format prefixed + * by a length byte (as expected by TS 27.005) or NULL for default SMSC + * ((const char **)data)[1] is SMS in PDU format as an ASCII hex string + * less the SMSC address + * TP-Layer-Length is be "strlen(((const char **)data)[1])/2" + * + * "response" is a const RIL_SMS_Response * + * + * Based on the return error, caller decides to resend if sending sms + * fails. SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) + * and GENERIC_FAILURE means no retry (i.e. error cause is 500) + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SMS_SEND_FAIL_RETRY + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_SEND_SMS_EXPECT_MORE 26 + + +/** + * RIL_REQUEST_SETUP_DATA_CALL + * + * Setup a packet data connection. If RIL_Data_Call_Response_v6.status + * return success it is added to the list of data calls and a + * RIL_UNSOL_DATA_CALL_LIST_CHANGED is sent. The call remains in the + * list until RIL_REQUEST_DEACTIVATE_DATA_CALL is issued or the + * radio is powered off/on. This list is returned by RIL_REQUEST_DATA_CALL_LIST + * and RIL_UNSOL_DATA_CALL_LIST_CHANGED. + * + * The RIL is expected to: + * - Create one data call context. + * - Create and configure a dedicated interface for the context + * - The interface must be point to point. + * - The interface is configured with one or more addresses and + * is capable of sending and receiving packets. The prefix length + * of the addresses must be /32 for IPv4 and /128 for IPv6. + * - Must NOT change the linux routing table. + * - Support up to RIL_REQUEST_DATA_REGISTRATION_STATE response[5] + * number of simultaneous data call contexts. + * + * "data" is a const char ** + * ((const char **)data)[0] Radio technology to use: 0-CDMA, 1-GSM/UMTS, 2... + * for values above 2 this is RIL_RadioTechnology + 2. + * ((const char **)data)[1] is a RIL_DataProfile (support is optional) + * ((const char **)data)[2] is the APN to connect to if radio technology is GSM/UMTS. This APN will + * override the one in the profile. NULL indicates no APN overrride. + * ((const char **)data)[3] is the username for APN, or NULL + * ((const char **)data)[4] is the password for APN, or NULL + * ((const char **)data)[5] is the PAP / CHAP auth type. Values: + * 0 => PAP and CHAP is never performed. + * 1 => PAP may be performed; CHAP is never performed. + * 2 => CHAP may be performed; PAP is never performed. + * 3 => PAP / CHAP may be performed - baseband dependent. + * ((const char **)data)[6] is the connection type to request must be one of the + * PDP_type values in TS 27.007 section 10.1.1. + * For example, "IP", "IPV6", "IPV4V6", or "PPP". + * ((const char **)data)[7] Optional connection property parameters, format to be defined. + * + * "response" is a RIL_Data_Call_Response_v6 + * + * FIXME may need way to configure QoS settings + * + * Valid errors: + * SUCCESS should be returned on both success and failure of setup with + * the RIL_Data_Call_Response_v6.status containing the actual status. + * For all other errors the RIL_Data_Call_Resonse_v6 is ignored. + * + * Other errors could include: + * RADIO_NOT_AVAILABLE, GENERIC_FAILURE, OP_NOT_ALLOWED_BEFORE_REG_TO_NW, + * OP_NOT_ALLOWED_DURING_VOICE_CALL and REQUEST_NOT_SUPPORTED. + * + * See also: RIL_REQUEST_DEACTIVATE_DATA_CALL + */ +#define RIL_REQUEST_SETUP_DATA_CALL 27 + + +/** + * RIL_REQUEST_SIM_IO + * + * Request SIM I/O operation. + * This is similar to the TS 27.007 "restricted SIM" operation + * where it assumes all of the EF selection will be done by the + * callee. + * + * "data" is a const RIL_SIM_IO_v6 * + * Please note that RIL_SIM_IO has a "PIN2" field which may be NULL, + * or may specify a PIN2 for operations that require a PIN2 (eg + * updating FDN records) + * + * "response" is a const RIL_SIM_IO_Response * + * + * Arguments and responses that are unused for certain + * values of "command" should be ignored or set to NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * SIM_PIN2 + * SIM_PUK2 + */ +#define RIL_REQUEST_SIM_IO 28 + +/** + * RIL_REQUEST_SEND_USSD + * + * Send a USSD message + * + * If a USSD session already exists, the message should be sent in the + * context of that session. Otherwise, a new session should be created. + * + * The network reply should be reported via RIL_UNSOL_ON_USSD + * + * Only one USSD session may exist at a time, and the session is assumed + * to exist until: + * a) The android system invokes RIL_REQUEST_CANCEL_USSD + * b) The implementation sends a RIL_UNSOL_ON_USSD with a type code + * of "0" (USSD-Notify/no further action) or "2" (session terminated) + * + * "data" is a const char * containing the USSD request in UTF-8 format + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * FDN_CHECK_FAILURE + * GENERIC_FAILURE + * + * See also: RIL_REQUEST_CANCEL_USSD, RIL_UNSOL_ON_USSD + */ + +#define RIL_REQUEST_SEND_USSD 29 + +/** + * RIL_REQUEST_CANCEL_USSD + * + * Cancel the current USSD session if one exists + * + * "data" is null + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_CANCEL_USSD 30 + +/** + * RIL_REQUEST_GET_CLIR + * + * Gets current CLIR status + * "data" is NULL + * "response" is int * + * ((int *)data)[0] is "n" parameter from TS 27.007 7.7 + * ((int *)data)[1] is "m" parameter from TS 27.007 7.7 + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_GET_CLIR 31 + +/** + * RIL_REQUEST_SET_CLIR + * + * "data" is int * + * ((int *)data)[0] is "n" parameter from TS 27.007 7.7 + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_SET_CLIR 32 + +/** + * RIL_REQUEST_QUERY_CALL_FORWARD_STATUS + * + * "data" is const RIL_CallForwardInfo * + * + * "response" is const RIL_CallForwardInfo ** + * "response" points to an array of RIL_CallForwardInfo *'s, one for + * each distinct registered phone number. + * + * For example, if data is forwarded to +18005551212 and voice is forwarded + * to +18005559999, then two separate RIL_CallForwardInfo's should be returned + * + * If, however, both data and voice are forwarded to +18005551212, then + * a single RIL_CallForwardInfo can be returned with the service class + * set to "data + voice = 3") + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_QUERY_CALL_FORWARD_STATUS 33 + + +/** + * RIL_REQUEST_SET_CALL_FORWARD + * + * Configure call forward rule + * + * "data" is const RIL_CallForwardInfo * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_SET_CALL_FORWARD 34 + + +/** + * RIL_REQUEST_QUERY_CALL_WAITING + * + * Query current call waiting state + * + * "data" is const int * + * ((const int *)data)[0] is the TS 27.007 service class to query. + * "response" is a const int * + * ((const int *)response)[0] is 0 for "disabled" and 1 for "enabled" + * + * If ((const int *)response)[0] is = 1, then ((const int *)response)[1] + * must follow, with the TS 27.007 service class bit vector of services + * for which call waiting is enabled. + * + * For example, if ((const int *)response)[0] is 1 and + * ((const int *)response)[1] is 3, then call waiting is enabled for data + * and voice and disabled for everything else + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_QUERY_CALL_WAITING 35 + + +/** + * RIL_REQUEST_SET_CALL_WAITING + * + * Configure current call waiting state + * + * "data" is const int * + * ((const int *)data)[0] is 0 for "disabled" and 1 for "enabled" + * ((const int *)data)[1] is the TS 27.007 service class bit vector of + * services to modify + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_SET_CALL_WAITING 36 + +/** + * RIL_REQUEST_SMS_ACKNOWLEDGE + * + * Acknowledge successful or failed receipt of SMS previously indicated + * via RIL_UNSOL_RESPONSE_NEW_SMS + * + * "data" is int * + * ((int *)data)[0] is 1 on successful receipt + * (basically, AT+CNMA=1 from TS 27.005 + * is 0 on failed receipt + * (basically, AT+CNMA=2 from TS 27.005) + * ((int *)data)[1] if data[0] is 0, this contains the failure cause as defined + * in TS 23.040, 9.2.3.22. Currently only 0xD3 (memory + * capacity exceeded) and 0xFF (unspecified error) are + * reported. + * + * "response" is NULL + * + * FIXME would like request that specified RP-ACK/RP-ERROR PDU + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_SMS_ACKNOWLEDGE 37 + +/** + * RIL_REQUEST_GET_IMEI - DEPRECATED + * + * Get the device IMEI, including check digit + * + * The request is DEPRECATED, use RIL_REQUEST_DEVICE_IDENTITY + * Valid when RadioState is not RADIO_STATE_UNAVAILABLE + * + * "data" is NULL + * "response" is a const char * containing the IMEI + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_GET_IMEI 38 + +/** + * RIL_REQUEST_GET_IMEISV - DEPRECATED + * + * Get the device IMEISV, which should be two decimal digits + * + * The request is DEPRECATED, use RIL_REQUEST_DEVICE_IDENTITY + * Valid when RadioState is not RADIO_STATE_UNAVAILABLE + * + * "data" is NULL + * "response" is a const char * containing the IMEISV + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_GET_IMEISV 39 + + +/** + * RIL_REQUEST_ANSWER + * + * Answer incoming call + * + * Will not be called for WAITING calls. + * RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE will be used in this case + * instead + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_ANSWER 40 + +/** + * RIL_REQUEST_DEACTIVATE_DATA_CALL + * + * Deactivate packet data connection and remove from the + * data call list if SUCCESS is returned. Any other return + * values should also try to remove the call from the list, + * but that may not be possible. In any event a + * RIL_REQUEST_RADIO_POWER off/on must clear the list. An + * RIL_UNSOL_DATA_CALL_LIST_CHANGED is not expected to be + * issued because of an RIL_REQUEST_DEACTIVATE_DATA_CALL. + * + * "data" is const char ** + * ((char**)data)[0] indicating CID + * ((char**)data)[1] indicating Disconnect Reason + * 0 => No specific reason specified + * 1 => Radio shutdown requested + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + * See also: RIL_REQUEST_SETUP_DATA_CALL + */ +#define RIL_REQUEST_DEACTIVATE_DATA_CALL 41 + +/** + * RIL_REQUEST_QUERY_FACILITY_LOCK + * + * Query the status of a facility lock state + * + * "data" is const char ** + * ((const char **)data)[0] is the facility string code from TS 27.007 7.4 + * (eg "AO" for BAOC, "SC" for SIM lock) + * ((const char **)data)[1] is the password, or "" if not required + * ((const char **)data)[2] is the TS 27.007 service class bit vector of + * services to query + * ((const char **)data)[3] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * This is only applicable in the case of Fixed Dialing Numbers + * (FDN) requests. + * + * "response" is an int * + * ((const int *)response) 0 is the TS 27.007 service class bit vector of + * services for which the specified barring facility + * is active. "0" means "disabled for all" + * + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_QUERY_FACILITY_LOCK 42 + +/** + * RIL_REQUEST_SET_FACILITY_LOCK + * + * Enable/disable one facility lock + * + * "data" is const char ** + * + * ((const char **)data)[0] = facility string code from TS 27.007 7.4 + * (eg "AO" for BAOC) + * ((const char **)data)[1] = "0" for "unlock" and "1" for "lock" + * ((const char **)data)[2] = password + * ((const char **)data)[3] = string representation of decimal TS 27.007 + * service class bit vector. Eg, the string + * "1" means "set this facility for voice services" + * ((const char **)data)[4] = AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * This is only applicable in the case of Fixed Dialing Numbers + * (FDN) requests. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_SET_FACILITY_LOCK 43 + +/** + * RIL_REQUEST_CHANGE_BARRING_PASSWORD + * + * Change call barring facility password + * + * "data" is const char ** + * + * ((const char **)data)[0] = facility string code from TS 27.007 7.4 + * (eg "AO" for BAOC) + * ((const char **)data)[1] = old password + * ((const char **)data)[2] = new password + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CHANGE_BARRING_PASSWORD 44 + +/** + * RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE + * + * Query current network selectin mode + * + * "data" is NULL + * + * "response" is int * + * ((const int *)response)[0] is + * 0 for automatic selection + * 1 for manual selection + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE 45 + +/** + * RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC + * + * Specify that the network should be selected automatically + * + * "data" is NULL + * "response" is NULL + * + * This request must not respond until the new operator is selected + * and registered + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * ILLEGAL_SIM_OR_ME + * GENERIC_FAILURE + * + * Note: Returns ILLEGAL_SIM_OR_ME when the failure is permanent and + * no retries needed, such as illegal SIM or ME. + * Returns GENERIC_FAILURE for all other causes that might be + * fixed by retries. + * + */ +#define RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC 46 + +/** + * RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL + * + * Manually select a specified network. + * + * "data" is const char * specifying MCCMNC of network to select (eg "310170") + * "response" is NULL + * + * This request must not respond until the new operator is selected + * and registered + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * ILLEGAL_SIM_OR_ME + * GENERIC_FAILURE + * + * Note: Returns ILLEGAL_SIM_OR_ME when the failure is permanent and + * no retries needed, such as illegal SIM or ME. + * Returns GENERIC_FAILURE for all other causes that might be + * fixed by retries. + * + */ +#define RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL 47 + +/** + * RIL_REQUEST_QUERY_AVAILABLE_NETWORKS + * + * Scans for available networks + * + * "data" is NULL + * "response" is const char ** that should be an array of n*4 strings, where + * n is the number of available networks + * For each available network: + * + * ((const char **)response)[n+0] is long alpha ONS or EONS + * ((const char **)response)[n+1] is short alpha ONS or EONS + * ((const char **)response)[n+2] is 5 or 6 digit numeric code (MCC + MNC) + * ((const char **)response)[n+3] is a string value of the status: + * "unknown" + * "available" + * "current" + * "forbidden" + * + * This request must not respond until the new operator is selected + * and registered + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_QUERY_AVAILABLE_NETWORKS 48 + +/** + * RIL_REQUEST_DTMF_START + * + * Start playing a DTMF tone. Continue playing DTMF tone until + * RIL_REQUEST_DTMF_STOP is received + * + * If a RIL_REQUEST_DTMF_START is received while a tone is currently playing, + * it should cancel the previous tone and play the new one. + * + * "data" is a char * + * ((char *)data)[0] is a single character with one of 12 values: 0-9,*,# + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + * See also: RIL_REQUEST_DTMF, RIL_REQUEST_DTMF_STOP + */ +#define RIL_REQUEST_DTMF_START 49 + +/** + * RIL_REQUEST_DTMF_STOP + * + * Stop playing a currently playing DTMF tone. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + * See also: RIL_REQUEST_DTMF, RIL_REQUEST_DTMF_START + */ +#define RIL_REQUEST_DTMF_STOP 50 + +/** + * RIL_REQUEST_BASEBAND_VERSION + * + * Return string value indicating baseband version, eg + * response from AT+CGMR + * + * "data" is NULL + * "response" is const char * containing version string for log reporting + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_BASEBAND_VERSION 51 + +/** + * RIL_REQUEST_SEPARATE_CONNECTION + * + * Separate a party from a multiparty call placing the multiparty call + * (less the specified party) on hold and leaving the specified party + * as the only other member of the current (active) call + * + * Like AT+CHLD=2x + * + * See TS 22.084 1.3.8.2 (iii) + * TS 22.030 6.5.5 "Entering "2X followed by send" + * TS 27.007 "AT+CHLD=2x" + * + * "data" is an int * + * (int *)data)[0] contains Connection index (value of 'x' in CHLD above) "response" is NULL + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ +#define RIL_REQUEST_SEPARATE_CONNECTION 52 + + +/** + * RIL_REQUEST_SET_MUTE + * + * Turn on or off uplink (microphone) mute. + * + * Will only be sent while voice call is active. + * Will always be reset to "disable mute" when a new voice call is initiated + * + * "data" is an int * + * (int *)data)[0] is 1 for "enable mute" and 0 for "disable mute" + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_SET_MUTE 53 + +/** + * RIL_REQUEST_GET_MUTE + * + * Queries the current state of the uplink mute setting + * + * "data" is NULL + * "response" is an int * + * (int *)response)[0] is 1 for "mute enabled" and 0 for "mute disabled" + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_GET_MUTE 54 + +/** + * RIL_REQUEST_QUERY_CLIP + * + * Queries the status of the CLIP supplementary service + * + * (for MMI code "*#30#") + * + * "data" is NULL + * "response" is an int * + * (int *)response)[0] is 1 for "CLIP provisioned" + * and 0 for "CLIP not provisioned" + * and 2 for "unknown, e.g. no network etc" + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ + +#define RIL_REQUEST_QUERY_CLIP 55 + +/** + * RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE - Deprecated use the status + * field in RIL_Data_Call_Response_v6. + * + * Requests the failure cause code for the most recently failed PDP + * context or CDMA data connection active + * replaces RIL_REQUEST_LAST_PDP_FAIL_CAUSE + * + * "data" is NULL + * + * "response" is a "int *" + * ((int *)response)[0] is an integer cause code defined in TS 24.008 + * section 6.1.3.1.3 or close approximation + * + * If the implementation does not have access to the exact cause codes, + * then it should return one of the values listed in + * RIL_DataCallFailCause, as the UI layer needs to distinguish these + * cases for error notification + * and potential retries. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + * See also: RIL_REQUEST_LAST_CALL_FAIL_CAUSE + * + * Deprecated use the status field in RIL_Data_Call_Response_v6. + */ + +#define RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE 56 + +/** + * RIL_REQUEST_DATA_CALL_LIST + * + * Returns the data call list. An entry is added when a + * RIL_REQUEST_SETUP_DATA_CALL is issued and removed on a + * RIL_REQUEST_DEACTIVATE_DATA_CALL. The list is emptied + * when RIL_REQUEST_RADIO_POWER off/on is issued. + * + * "data" is NULL + * "response" is an array of RIL_Data_Call_Response_v6 + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * + * See also: RIL_UNSOL_DATA_CALL_LIST_CHANGED + */ + +#define RIL_REQUEST_DATA_CALL_LIST 57 + +/** + * RIL_REQUEST_RESET_RADIO - DEPRECATED + * + * Request a radio reset. The RIL implementation may postpone + * the reset until after this request is responded to if the baseband + * is presently busy. + * + * The request is DEPRECATED, use RIL_REQUEST_RADIO_POWER + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_RESET_RADIO 58 + +/** + * RIL_REQUEST_OEM_HOOK_RAW + * + * This request reserved for OEM-specific uses. It passes raw byte arrays + * back and forth. + * + * It can be invoked on the Java side from + * com.android.internal.telephony.Phone.invokeOemRilRequestRaw() + * + * "data" is a char * of bytes copied from the byte[] data argument in java + * "response" is a char * of bytes that will returned via the + * caller's "response" Message here: + * (byte[])(((AsyncResult)response.obj).result) + * + * An error response here will result in + * (((AsyncResult)response.obj).result) == null and + * (((AsyncResult)response.obj).exception) being an instance of + * com.android.internal.telephony.gsm.CommandException + * + * Valid errors: + * All + */ + +#define RIL_REQUEST_OEM_HOOK_RAW 59 + +/** + * RIL_REQUEST_OEM_HOOK_STRINGS + * + * This request reserved for OEM-specific uses. It passes strings + * back and forth. + * + * It can be invoked on the Java side from + * com.android.internal.telephony.Phone.invokeOemRilRequestStrings() + * + * "data" is a const char **, representing an array of null-terminated UTF-8 + * strings copied from the "String[] strings" argument to + * invokeOemRilRequestStrings() + * + * "response" is a const char **, representing an array of null-terminated UTF-8 + * stings that will be returned via the caller's response message here: + * + * (String[])(((AsyncResult)response.obj).result) + * + * An error response here will result in + * (((AsyncResult)response.obj).result) == null and + * (((AsyncResult)response.obj).exception) being an instance of + * com.android.internal.telephony.gsm.CommandException + * + * Valid errors: + * All + */ + +#define RIL_REQUEST_OEM_HOOK_STRINGS 60 + +/** + * RIL_REQUEST_SCREEN_STATE + * + * Indicates the current state of the screen. When the screen is off, the + * RIL should notify the baseband to suppress certain notifications (eg, + * signal strength and changes in LAC/CID or BID/SID/NID/latitude/longitude) + * in an effort to conserve power. These notifications should resume when the + * screen is on. + * + * "data" is int * + * ((int *)data)[0] is == 1 for "Screen On" + * ((int *)data)[0] is == 0 for "Screen Off" + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * GENERIC_FAILURE + */ +#define RIL_REQUEST_SCREEN_STATE 61 + + +/** + * RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION + * + * Enables/disables supplementary service related notifications + * from the network. + * + * Notifications are reported via RIL_UNSOL_SUPP_SVC_NOTIFICATION. + * + * "data" is int * + * ((int *)data)[0] is == 1 for notifications enabled + * ((int *)data)[0] is == 0 for notifications disabled + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + * See also: RIL_UNSOL_SUPP_SVC_NOTIFICATION. + */ +#define RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION 62 + +/** + * RIL_REQUEST_WRITE_SMS_TO_SIM + * + * Stores a SMS message to SIM memory. + * + * "data" is RIL_SMS_WriteArgs * + * + * "response" is int * + * ((const int *)response)[0] is the record index where the message is stored. + * + * Valid errors: + * SUCCESS + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_WRITE_SMS_TO_SIM 63 + +/** + * RIL_REQUEST_DELETE_SMS_ON_SIM + * + * Deletes a SMS message from SIM memory. + * + * "data" is int * + * ((int *)data)[0] is the record index of the message to delete. + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_DELETE_SMS_ON_SIM 64 + +/** + * RIL_REQUEST_SET_BAND_MODE + * + * Assign a specified band for RF configuration. + * + * "data" is int * + * ((int *)data)[0] is == 0 for "unspecified" (selected by baseband automatically) + * ((int *)data)[0] is == 1 for "EURO band" (GSM-900 / DCS-1800 / WCDMA-IMT-2000) + * ((int *)data)[0] is == 2 for "US band" (GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900) + * ((int *)data)[0] is == 3 for "JPN band" (WCDMA-800 / WCDMA-IMT-2000) + * ((int *)data)[0] is == 4 for "AUS band" (GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000) + * ((int *)data)[0] is == 5 for "AUS band 2" (GSM-900 / DCS-1800 / WCDMA-850) + * ((int *)data)[0] is == 6 for "Cellular (800-MHz Band)" + * ((int *)data)[0] is == 7 for "PCS (1900-MHz Band)" + * ((int *)data)[0] is == 8 for "Band Class 3 (JTACS Band)" + * ((int *)data)[0] is == 9 for "Band Class 4 (Korean PCS Band)" + * ((int *)data)[0] is == 10 for "Band Class 5 (450-MHz Band)" + * ((int *)data)[0] is == 11 for "Band Class 6 (2-GMHz IMT2000 Band)" + * ((int *)data)[0] is == 12 for "Band Class 7 (Upper 700-MHz Band)" + * ((int *)data)[0] is == 13 for "Band Class 8 (1800-MHz Band)" + * ((int *)data)[0] is == 14 for "Band Class 9 (900-MHz Band)" + * ((int *)data)[0] is == 15 for "Band Class 10 (Secondary 800-MHz Band)" + * ((int *)data)[0] is == 16 for "Band Class 11 (400-MHz European PAMR Band)" + * ((int *)data)[0] is == 17 for "Band Class 15 (AWS Band)" + * ((int *)data)[0] is == 18 for "Band Class 16 (US 2.5-GHz Band)" + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_SET_BAND_MODE 65 + +/** + * RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE + * + * Query the list of band mode supported by RF. + * + * "data" is NULL + * + * "response" is int * + * "response" points to an array of int's, the int[0] is the size of array, reset is one for + * each available band mode. + * + * 0 for "unspecified" (selected by baseband automatically) + * 1 for "EURO band" (GSM-900 / DCS-1800 / WCDMA-IMT-2000) + * 2 for "US band" (GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900) + * 3 for "JPN band" (WCDMA-800 / WCDMA-IMT-2000) + * 4 for "AUS band" (GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000) + * 5 for "AUS band 2" (GSM-900 / DCS-1800 / WCDMA-850) + * 6 for "Cellular (800-MHz Band)" + * 7 for "PCS (1900-MHz Band)" + * 8 for "Band Class 3 (JTACS Band)" + * 9 for "Band Class 4 (Korean PCS Band)" + * 10 for "Band Class 5 (450-MHz Band)" + * 11 for "Band Class 6 (2-GMHz IMT2000 Band)" + * 12 for "Band Class 7 (Upper 700-MHz Band)" + * 13 for "Band Class 8 (1800-MHz Band)" + * 14 for "Band Class 9 (900-MHz Band)" + * 15 for "Band Class 10 (Secondary 800-MHz Band)" + * 16 for "Band Class 11 (400-MHz European PAMR Band)" + * 17 for "Band Class 15 (AWS Band)" + * 18 for "Band Class 16 (US 2.5-GHz Band)" + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + * See also: RIL_REQUEST_SET_BAND_MODE + */ +#define RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE 66 + +/** + * RIL_REQUEST_STK_GET_PROFILE + * + * Requests the profile of SIM tool kit. + * The profile indicates the SAT/USAT features supported by ME. + * The SAT/USAT features refer to 3GPP TS 11.14 and 3GPP TS 31.111 + * + * "data" is NULL + * + * "response" is a const char * containing SAT/USAT profile + * in hexadecimal format string starting with first byte of terminal profile + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * RIL_E_GENERIC_FAILURE + */ +#define RIL_REQUEST_STK_GET_PROFILE 67 + +/** + * RIL_REQUEST_STK_SET_PROFILE + * + * Download the STK terminal profile as part of SIM initialization + * procedure + * + * "data" is a const char * containing SAT/USAT profile + * in hexadecimal format string starting with first byte of terminal profile + * + * "response" is NULL + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * RIL_E_GENERIC_FAILURE + */ +#define RIL_REQUEST_STK_SET_PROFILE 68 + +/** + * RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND + * + * Requests to send a SAT/USAT envelope command to SIM. + * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111 + * + * "data" is a const char * containing SAT/USAT command + * in hexadecimal format string starting with command tag + * + * "response" is a const char * containing SAT/USAT response + * in hexadecimal format string starting with first byte of response + * (May be NULL) + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * RIL_E_GENERIC_FAILURE + */ +#define RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND 69 + +/** + * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE + * + * Requests to send a terminal response to SIM for a received + * proactive command + * + * "data" is a const char * containing SAT/USAT response + * in hexadecimal format string starting with first byte of response data + * + * "response" is NULL + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * RIL_E_GENERIC_FAILURE + */ +#define RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE 70 + +/** + * RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM + * + * When STK application gets RIL_UNSOL_STK_CALL_SETUP, the call actually has + * been initialized by ME already. (We could see the call has been in the 'call + * list') So, STK application needs to accept/reject the call according as user + * operations. + * + * "data" is int * + * ((int *)data)[0] is > 0 for "accept" the call setup + * ((int *)data)[0] is == 0 for "reject" the call setup + * + * "response" is NULL + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * RIL_E_GENERIC_FAILURE + */ +#define RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM 71 + +/** + * RIL_REQUEST_EXPLICIT_CALL_TRANSFER + * + * Connects the two calls and disconnects the subscriber from both calls. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + */ +#define RIL_REQUEST_EXPLICIT_CALL_TRANSFER 72 + +/** + * RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE + * + * Requests to set the preferred network type for searching and registering + * (CS/PS domain, RAT, and operation mode) + * + * "data" is int * which is RIL_PreferredNetworkType + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * MODE_NOT_SUPPORTED + */ +#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE 73 + +/** + * RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE + * + * Query the preferred network type (CS/PS domain, RAT, and operation mode) + * for searching and registering + * + * "data" is NULL + * + * "response" is int * + * ((int *)reponse)[0] is == RIL_PreferredNetworkType + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + * See also: RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE + */ +#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE 74 + +/** + * RIL_REQUEST_NEIGHBORING_CELL_IDS + * + * Request neighboring cell id in GSM network + * + * "data" is NULL + * "response" must be a " const RIL_NeighboringCell** " + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_GET_NEIGHBORING_CELL_IDS 75 + +/** + * RIL_REQUEST_SET_LOCATION_UPDATES + * + * Enables/disables network state change notifications due to changes in + * LAC and/or CID (for GSM) or BID/SID/NID/latitude/longitude (for CDMA). + * Basically +CREG=2 vs. +CREG=1 (TS 27.007). + * + * Note: The RIL implementation should default to "updates enabled" + * when the screen is on and "updates disabled" when the screen is off. + * + * "data" is int * + * ((int *)data)[0] is == 1 for updates enabled (+CREG=2) + * ((int *)data)[0] is == 0 for updates disabled (+CREG=1) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + * See also: RIL_REQUEST_SCREEN_STATE, RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED + */ +#define RIL_REQUEST_SET_LOCATION_UPDATES 76 + +/** + * RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE + * + * Request to set the location where the CDMA subscription shall + * be retrieved + * + * "data" is int * + * ((int *)data)[0] is == RIL_CdmaSubscriptionSource + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * SIM_ABSENT + * SUBSCRIPTION_NOT_AVAILABLE + * + * See also: RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE + */ +#define RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE 77 + +/** + * RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE + * + * Request to set the roaming preferences in CDMA + * + * "data" is int * + * ((int *)data)[0] is == 0 for Home Networks only, as defined in PRL + * ((int *)data)[0] is == 1 for Roaming on Affiliated networks, as defined in PRL + * ((int *)data)[0] is == 2 for Roaming on Any Network, as defined in the PRL + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE 78 + +/** + * RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE + * + * Request the actual setting of the roaming preferences in CDMA in the modem + * + * "data" is NULL + * + * "response" is int * + * ((int *)response)[0] is == 0 for Home Networks only, as defined in PRL + * ((int *)response)[0] is == 1 for Roaming on Affiliated networks, as defined in PRL + * ((int *)response)[0] is == 2 for Roaming on Any Network, as defined in the PRL + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE 79 + +/** + * RIL_REQUEST_SET_TTY_MODE + * + * Request to set the TTY mode + * + * "data" is int * + * ((int *)data)[0] is == 0 for TTY off + * ((int *)data)[0] is == 1 for TTY Full + * ((int *)data)[0] is == 2 for TTY HCO (hearing carryover) + * ((int *)data)[0] is == 3 for TTY VCO (voice carryover) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_SET_TTY_MODE 80 + +/** + * RIL_REQUEST_QUERY_TTY_MODE + * + * Request the setting of TTY mode + * + * "data" is NULL + * + * "response" is int * + * ((int *)response)[0] is == 0 for TTY off + * ((int *)response)[0] is == 1 for TTY Full + * ((int *)response)[0] is == 2 for TTY HCO (hearing carryover) + * ((int *)response)[0] is == 3 for TTY VCO (voice carryover) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_QUERY_TTY_MODE 81 + +/** + * RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE + * + * Request to set the preferred voice privacy mode used in voice + * scrambling + * + * "data" is int * + * ((int *)data)[0] is == 0 for Standard Privacy Mode (Public Long Code Mask) + * ((int *)data)[0] is == 1 for Enhanced Privacy Mode (Private Long Code Mask) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE 82 + +/** + * RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE + * + * Request the setting of preferred voice privacy mode + * + * "data" is NULL + * + * "response" is int * + * ((int *)response)[0] is == 0 for Standard Privacy Mode (Public Long Code Mask) + * ((int *)response)[0] is == 1 for Enhanced Privacy Mode (Private Long Code Mask) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE 83 + +/** + * RIL_REQUEST_CDMA_FLASH + * + * Send FLASH + * + * "data" is const char * + * ((const char *)data)[0] is a FLASH string + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CDMA_FLASH 84 + +/** + * RIL_REQUEST_CDMA_BURST_DTMF + * + * Send DTMF string + * + * "data" is const char ** + * ((const char **)data)[0] is a DTMF string + * ((const char **)data)[1] is the DTMF ON length in milliseconds, or 0 to use + * default + * ((const char **)data)[2] is the DTMF OFF length in milliseconds, or 0 to use + * default + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CDMA_BURST_DTMF 85 + +/** + * RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY + * + * Takes a 26 digit string (20 digit AKEY + 6 digit checksum). + * If the checksum is valid the 20 digit AKEY is written to NV, + * replacing the existing AKEY no matter what it was before. + * + * "data" is const char * + * ((const char *)data)[0] is a 26 digit string (ASCII digits '0'-'9') + * where the last 6 digits are a checksum of the + * first 20, as specified in TR45.AHAG + * "Common Cryptographic Algorithms, Revision D.1 + * Section 2.2" + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY 86 + +/** + * RIL_REQUEST_CDMA_SEND_SMS + * + * Send a CDMA SMS message + * + * "data" is const RIL_CDMA_SMS_Message * + * + * "response" is a const RIL_SMS_Response * + * + * Based on the return error, caller decides to resend if sending sms + * fails. The CDMA error class is derived as follows, + * SUCCESS is error class 0 (no error) + * SMS_SEND_FAIL_RETRY is error class 2 (temporary failure) + * and GENERIC_FAILURE is error class 3 (permanent and no retry) + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SMS_SEND_FAIL_RETRY + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CDMA_SEND_SMS 87 + +/** + * RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE + * + * Acknowledge the success or failure in the receipt of SMS + * previously indicated via RIL_UNSOL_RESPONSE_CDMA_NEW_SMS + * + * "data" is const RIL_CDMA_SMS_Ack * + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE 88 + +/** + * RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG + * + * Request the setting of GSM/WCDMA Cell Broadcast SMS config. + * + * "data" is NULL + * + * "response" is a const RIL_GSM_BroadcastSmsConfigInfo ** + * "responselen" is count * sizeof (RIL_GSM_BroadcastSmsConfigInfo *) + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG 89 + +/** + * RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG + * + * Set GSM/WCDMA Cell Broadcast SMS config + * + * "data" is a const RIL_GSM_BroadcastSmsConfigInfo ** + * "datalen" is count * sizeof(RIL_GSM_BroadcastSmsConfigInfo *) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG 90 + +/** + * RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION + * +* Enable or disable the reception of GSM/WCDMA Cell Broadcast SMS + * + * "data" is const int * + * (const int *)data[0] indicates to activate or turn off the + * reception of GSM/WCDMA Cell Broadcast SMS, 0-1, + * 0 - Activate, 1 - Turn off + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION 91 + +/** + * RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG + * + * Request the setting of CDMA Broadcast SMS config + * + * "data" is NULL + * + * "response" is a const RIL_CDMA_BroadcastSmsConfigInfo ** + * "responselen" is count * sizeof (RIL_CDMA_BroadcastSmsConfigInfo *) + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG 92 + +/** + * RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG + * + * Set CDMA Broadcast SMS config + * + * "data" is an const RIL_CDMA_BroadcastSmsConfigInfo ** + * "datalen" is count * sizeof(const RIL_CDMA_BroadcastSmsConfigInfo *) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG 93 + +/** + * RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION + * + * Enable or disable the reception of CDMA Broadcast SMS + * + * "data" is const int * + * (const int *)data[0] indicates to activate or turn off the + * reception of CDMA Broadcast SMS, 0-1, + * 0 - Activate, 1 - Turn off + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION 94 + +/** + * RIL_REQUEST_CDMA_SUBSCRIPTION + * + * Request the device MDN / H_SID / H_NID. + * + * The request is only allowed when CDMA subscription is available. When CDMA + * subscription is changed, application layer should re-issue the request to + * update the subscription information. + * + * If a NULL value is returned for any of the device id, it means that error + * accessing the device. + * + * "response" is const char ** + * ((const char **)response)[0] is MDN if CDMA subscription is available + * ((const char **)response)[1] is a comma separated list of H_SID (Home SID) if + * CDMA subscription is available, in decimal format + * ((const char **)response)[2] is a comma separated list of H_NID (Home NID) if + * CDMA subscription is available, in decimal format + * ((const char **)response)[3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available + * ((const char **)response)[4] is PRL version if CDMA subscription is available + * + * Valid errors: + * SUCCESS + * RIL_E_SUBSCRIPTION_NOT_AVAILABLE + */ + +#define RIL_REQUEST_CDMA_SUBSCRIPTION 95 + +/** + * RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM + * + * Stores a CDMA SMS message to RUIM memory. + * + * "data" is RIL_CDMA_SMS_WriteArgs * + * + * "response" is int * + * ((const int *)response)[0] is the record index where the message is stored. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM 96 + +/** + * RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM + * + * Deletes a CDMA SMS message from RUIM memory. + * + * "data" is int * + * ((int *)data)[0] is the record index of the message to delete. + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 97 + +/** + * RIL_REQUEST_DEVICE_IDENTITY + * + * Request the device ESN / MEID / IMEI / IMEISV. + * + * The request is always allowed and contains GSM and CDMA device identity; + * it substitutes the deprecated requests RIL_REQUEST_GET_IMEI and + * RIL_REQUEST_GET_IMEISV. + * + * If a NULL value is returned for any of the device id, it means that error + * accessing the device. + * + * When CDMA subscription is changed the ESN/MEID may change. The application + * layer should re-issue the request to update the device identity in this case. + * + * "response" is const char ** + * ((const char **)response)[0] is IMEI if GSM subscription is available + * ((const char **)response)[1] is IMEISV if GSM subscription is available + * ((const char **)response)[2] is ESN if CDMA subscription is available + * ((const char **)response)[3] is MEID if CDMA subscription is available + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_DEVICE_IDENTITY 98 + +/** + * RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE + * + * Request the radio's system selection module to exit emergency + * callback mode. RIL will not respond with SUCCESS until the modem has + * completely exited from Emergency Callback Mode. + * + * "data" is NULL + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE 99 + +/** + * RIL_REQUEST_GET_SMSC_ADDRESS + * + * Queries the default Short Message Service Center address on the device. + * + * "data" is NULL + * + * "response" is const char * containing the SMSC address. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_GET_SMSC_ADDRESS 100 + +/** + * RIL_REQUEST_SET_SMSC_ADDRESS + * + * Sets the default Short Message Service Center address on the device. + * + * "data" is const char * containing the SMSC address. + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_SET_SMSC_ADDRESS 101 + +/** + * RIL_REQUEST_REPORT_SMS_MEMORY_STATUS + * + * Indicates whether there is storage available for new SMS messages. + * + * "data" is int * + * ((int *)data)[0] is 1 if memory is available for storing new messages + * is 0 if memory capacity is exceeded + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_REPORT_SMS_MEMORY_STATUS 102 + +/** + * RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING + * + * Indicates that the StkSerivce is running and is + * ready to receive RIL_UNSOL_STK_XXXXX commands. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING 103 + +/** + * RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE + * + * Request to query the location where the CDMA subscription shall + * be retrieved + * + * "data" is NULL + * + * "response" is int * + * ((int *)data)[0] is == RIL_CdmaSubscriptionSource + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * SUBSCRIPTION_NOT_AVAILABLE + * + * See also: RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE + */ +#define RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE 104 + +/** + * RIL_REQUEST_ISIM_AUTHENTICATION + * + * Request the ISIM application on the UICC to perform AKA + * challenge/response algorithm for IMS authentication + * + * "data" is a const char * containing the challenge string in Base64 format + * "response" is a const char * containing the response in Base64 format + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_ISIM_AUTHENTICATION 105 + +/** + * RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU + * + * Acknowledge successful or failed receipt of SMS previously indicated + * via RIL_UNSOL_RESPONSE_NEW_SMS, including acknowledgement TPDU to send + * as the RP-User-Data element of the RP-ACK or RP-ERROR PDU. + * + * "data" is const char ** + * ((const char **)data)[0] is "1" on successful receipt (send RP-ACK) + * is "0" on failed receipt (send RP-ERROR) + * ((const char **)data)[1] is the acknowledgement TPDU in hexadecimal format + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU 106 + +/** + * RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS + * + * Requests to send a SAT/USAT envelope command to SIM. + * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111. + * + * This request has one difference from RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: + * the SW1 and SW2 status bytes from the UICC response are returned along with + * the response data, using the same structure as RIL_REQUEST_SIM_IO. + * + * The RIL implementation shall perform the normal processing of a '91XX' + * response in SW1/SW2 to retrieve the pending proactive command and send it + * as an unsolicited response, as RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND does. + * + * "data" is a const char * containing the SAT/USAT command + * in hexadecimal format starting with command tag + * + * "response" is a const RIL_SIM_IO_Response * + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * RIL_E_GENERIC_FAILURE + */ +#define RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS 107 + +/** + * RIL_REQUEST_VOICE_RADIO_TECH + * + * Query the radio technology type (3GPP/3GPP2) used for voice. Query is valid only + * when radio state is RADIO_STATE_ON + * + * "data" is NULL + * "response" is int * + * ((int *) response)[0] is of type const RIL_RadioTechnology + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_VOICE_RADIO_TECH 108 + +/** + * RIL_REQUEST_GET_CELL_INFO_LIST + * + * Request all of the current cell information known to the radio. The radio + * must a list of all current cells, including the neighboring cells. If for a particular + * cell information isn't known then the appropriate unknown value will be returned. + * This does not cause or change the rate of RIL_UNSOL_CELL_INFO_LIST. + * + * "data" is NULL + * + * "response" is an array of RIL_CellInfo. + */ +#define RIL_REQUEST_GET_CELL_INFO_LIST 109 + +/** + * RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE + * + * Sets the minimum time between when RIL_UNSOL_CELL_INFO_LIST should be invoked. + * A value of 0, means invoke RIL_UNSOL_CELL_INFO_LIST when any of the reported + * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue + * a RIL_UNSOL_CELL_INFO_LIST. + * + * "data" is int * + * ((int *)data)[0] is minimum time in milliseconds + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110 + +/* SAMSUNG REQUESTS */ +#define RIL_REQUEST_GET_CELL_BROADCAST_CONFIG 10002 + +#define RIL_REQUEST_SEND_ENCODED_USSD 10005 +#define RIL_REQUEST_SET_PDA_MEMORY_STATUS 10006 +#define RIL_REQUEST_GET_PHONEBOOK_STORAGE_INFO 10007 +#define RIL_REQUEST_GET_PHONEBOOK_ENTRY 10008 +#define RIL_REQUEST_ACCESS_PHONEBOOK_ENTRY 10009 +#define RIL_REQUEST_DIAL_VIDEO_CALL 10010 +#define RIL_REQUEST_CALL_DEFLECTION 10011 +#define RIL_REQUEST_READ_SMS_FROM_SIM 10012 +#define RIL_REQUEST_USIM_PB_CAPA 10013 +#define RIL_REQUEST_LOCK_INFO 10014 + +#define RIL_REQUEST_DIAL_EMERGENCY 10016 +#define RIL_REQUEST_GET_STOREAD_MSG_COUNT 10017 +#define RIL_REQUEST_STK_SIM_INIT_EVENT 10018 +#define RIL_REQUEST_GET_LINE_ID 10019 +#define RIL_REQUEST_SET_LINE_ID 10020 +#define RIL_REQUEST_GET_SERIAL_NUMBER 10021 +#define RIL_REQUEST_GET_MANUFACTURE_DATE_NUMBER 10022 +#define RIL_REQUEST_GET_BARCODE_NUMBER 10023 +#define RIL_REQUEST_UICC_GBA_AUTHENTICATE_BOOTSTRAP 10024 +#define RIL_REQUEST_UICC_GBA_AUTHENTICATE_NAF 10025 +#define RIL_REQUEST_SIM_TRANSMIT_BASIC 10026 +#define RIL_REQUEST_SIM_OPEN_CHANNEL 10027 +#define RIL_REQUEST_SIM_CLOSE_CHANNEL 10028 +#define RIL_REQUEST_SIM_TRANSMIT_CHANNEL 10029 +#define RIL_REQUEST_SIM_AUTH 10030 +#define RIL_REQUEST_PS_ATTACH 10031 +#define RIL_REQUEST_PS_DETACH 10032 +#define RIL_REQUEST_ACTIVATE_DATA_CALL 10033 +#define RIL_REQUEST_CHANGE_SIM_PERSO 10034 +#define RIL_REQUEST_ENTER_SIM_PERSO 10035 +#define RIL_REQUEST_GET_TIME_INFO 10036 +#define RIL_REQUEST_OMADM_SETUP_SESSION 10037 +#define RIL_REQUEST_OMADM_SERVER_START_SESSION 10038 +#define RIL_REQUEST_OMADM_CLIENT_START_SESSION 10039 +#define RIL_REQUEST_OMADM_SEND_DATA 10040 +#define RIL_REQUEST_CDMA_GET_DATAPROFILE 10041 +#define RIL_REQUEST_CDMA_SET_DATAPROFILE 10042 +#define RIL_REQUEST_CDMA_GET_SYSTEMPROPERTIES 10043 +#define RIL_REQUEST_CDMA_SET_SYSTEMPROPERTIES 10044 +#define RIL_REQUEST_SEND_SMS_COUNT 10045 +#define RIL_REQUEST_SEND_SMS_MSG 10046 +#define RIL_REQUEST_SEND_SMS_MSG_READ_STATUS 10047 +#define RIL_REQUEST_MODEM_HANGUP 10048 +#define RIL_REQUEST_SET_SIM_POWER 10049 +#define RIL_REQUEST_SET_PREFERRED_NETWORK_LIST 10050 +#define RIL_REQUEST_GET_PREFERRED_NETWORK_LIST 10051 +#define RIL_REQUEST_HANGUP_VT 10052 + + +/***********************************************************************/ + + +#define RIL_UNSOL_RESPONSE_BASE 1000 + +/** + * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED + * + * Indicate when value of RIL_RadioState has changed. + * + * Callee will invoke RIL_RadioStateRequest method on main thread + * + * "data" is NULL + */ + +#define RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED 1000 + + +/** + * RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED + * + * Indicate when call state has changed + * + * Callee will invoke RIL_REQUEST_GET_CURRENT_CALLS on main thread + * + * "data" is NULL + * + * Response should be invoked on, for example, + * "RING", "BUSY", "NO CARRIER", and also call state + * transitions (DIALING->ALERTING ALERTING->ACTIVE) + * + * Redundent or extraneous invocations are tolerated + */ +#define RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 1001 + + +/** + * RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED + * + * Called when the voice network state changed + * + * Callee will invoke the following requests on main thread: + * + * RIL_REQUEST_VOICE_REGISTRATION_STATE + * RIL_REQUEST_OPERATOR + * + * "data" is NULL + * + * FIXME should this happen when SIM records are loaded? (eg, for + * EONS) + */ +#define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 1002 + +/** + * RIL_UNSOL_RESPONSE_NEW_SMS + * + * Called when new SMS is received. + * + * "data" is const char * + * This is a pointer to a string containing the PDU of an SMS-DELIVER + * as an ascii string of hex digits. The PDU starts with the SMSC address + * per TS 27.005 (+CMT:) + * + * Callee will subsequently confirm the receipt of thei SMS with a + * RIL_REQUEST_SMS_ACKNOWLEDGE + * + * No new RIL_UNSOL_RESPONSE_NEW_SMS + * or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT messages should be sent until a + * RIL_REQUEST_SMS_ACKNOWLEDGE has been received + */ + +#define RIL_UNSOL_RESPONSE_NEW_SMS 1003 + +/** + * RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT + * + * Called when new SMS Status Report is received. + * + * "data" is const char * + * This is a pointer to a string containing the PDU of an SMS-STATUS-REPORT + * as an ascii string of hex digits. The PDU starts with the SMSC address + * per TS 27.005 (+CDS:). + * + * Callee will subsequently confirm the receipt of the SMS with a + * RIL_REQUEST_SMS_ACKNOWLEDGE + * + * No new RIL_UNSOL_RESPONSE_NEW_SMS + * or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT messages should be sent until a + * RIL_REQUEST_SMS_ACKNOWLEDGE has been received + */ + +#define RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT 1004 + +/** + * RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM + * + * Called when new SMS has been stored on SIM card + * + * "data" is const int * + * ((const int *)data)[0] contains the slot index on the SIM that contains + * the new message + */ + +#define RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM 1005 + +/** + * RIL_UNSOL_ON_USSD + * + * Called when a new USSD message is received. + * + * "data" is const char ** + * ((const char **)data)[0] points to a type code, which is + * one of these string values: + * "0" USSD-Notify -- text in ((const char **)data)[1] + * "1" USSD-Request -- text in ((const char **)data)[1] + * "2" Session terminated by network + * "3" other local client (eg, SIM Toolkit) has responded + * "4" Operation not supported + * "5" Network timeout + * + * The USSD session is assumed to persist if the type code is "1", otherwise + * the current session (if any) is assumed to have terminated. + * + * ((const char **)data)[1] points to a message string if applicable, which + * should always be in UTF-8. + */ +#define RIL_UNSOL_ON_USSD 1006 +/* Previously #define RIL_UNSOL_ON_USSD_NOTIFY 1006 */ + +/** + * RIL_UNSOL_ON_USSD_REQUEST + * + * Obsolete. Send via RIL_UNSOL_ON_USSD + */ +#define RIL_UNSOL_ON_USSD_REQUEST 1007 + + +/** + * RIL_UNSOL_NITZ_TIME_RECEIVED + * + * Called when radio has received a NITZ time message + * + * "data" is const char * pointing to NITZ time string + * in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt" + */ +#define RIL_UNSOL_NITZ_TIME_RECEIVED 1008 + +/** + * RIL_UNSOL_SIGNAL_STRENGTH + * + * Radio may report signal strength rather han have it polled. + * + * "data" is a const RIL_SignalStrength * + */ +#define RIL_UNSOL_SIGNAL_STRENGTH 1009 + + +/** + * RIL_UNSOL_DATA_CALL_LIST_CHANGED + * + * "data" is an array of RIL_Data_Call_Response_v6 identical to that + * returned by RIL_REQUEST_DATA_CALL_LIST. It is the complete list + * of current data contexts including new contexts that have been + * activated. A data call is only removed from this list when the + * framework sends a RIL_REQUEST_DEACTIVATE_DATA_CALL or the radio + * is powered off/on. + * + * See also: RIL_REQUEST_DATA_CALL_LIST + */ + +#define RIL_UNSOL_DATA_CALL_LIST_CHANGED 1010 + +/** + * RIL_UNSOL_SUPP_SVC_NOTIFICATION + * + * Reports supplementary service related notification from the network. + * + * "data" is a const RIL_SuppSvcNotification * + * + */ + +#define RIL_UNSOL_SUPP_SVC_NOTIFICATION 1011 + +/** + * RIL_UNSOL_STK_SESSION_END + * + * Indicate when STK session is terminated by SIM. + * + * "data" is NULL + */ +#define RIL_UNSOL_STK_SESSION_END 1012 + +/** + * RIL_UNSOL_STK_PROACTIVE_COMMAND + * + * Indicate when SIM issue a STK proactive command to applications + * + * "data" is a const char * containing SAT/USAT proactive command + * in hexadecimal format string starting with command tag + * + */ +#define RIL_UNSOL_STK_PROACTIVE_COMMAND 1013 + +/** + * RIL_UNSOL_STK_EVENT_NOTIFY + * + * Indicate when SIM notifies applcations some event happens. + * Generally, application does not need to have any feedback to + * SIM but shall be able to indicate appropriate messages to users. + * + * "data" is a const char * containing SAT/USAT commands or responses + * sent by ME to SIM or commands handled by ME, in hexadecimal format string + * starting with first byte of response data or command tag + * + */ +#define RIL_UNSOL_STK_EVENT_NOTIFY 1014 + +/** + * RIL_UNSOL_STK_CALL_SETUP + * + * Indicate when SIM wants application to setup a voice call. + * + * "data" is const int * + * ((const int *)data)[0] contains timeout value (in milliseconds) + */ +#define RIL_UNSOL_STK_CALL_SETUP 1015 + +/** + * RIL_UNSOL_SIM_SMS_STORAGE_FULL + * + * Indicates that SMS storage on the SIM is full. Sent when the network + * attempts to deliver a new SMS message. Messages cannot be saved on the + * SIM until space is freed. In particular, incoming Class 2 messages + * cannot be stored. + * + * "data" is null + * + */ +#define RIL_UNSOL_SIM_SMS_STORAGE_FULL 1016 + +/** + * RIL_UNSOL_SIM_REFRESH + * + * Indicates that file(s) on the SIM have been updated, or the SIM + * has been reinitialized. + * + * In the case where RIL is version 6 or older: + * "data" is an int * + * ((int *)data)[0] is a RIL_SimRefreshResult. + * ((int *)data)[1] is the EFID of the updated file if the result is + * SIM_FILE_UPDATE or NULL for any other result. + * + * In the case where RIL is version 7: + * "data" is a RIL_SimRefreshResponse_v7 * + * + * Note: If the SIM state changes as a result of the SIM refresh (eg, + * SIM_READY -> SIM_LOCKED_OR_ABSENT), RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED + * should be sent. + */ +#define RIL_UNSOL_SIM_REFRESH 1017 + +/** + * RIL_UNSOL_CALL_RING + * + * Ring indication for an incoming call (eg, RING or CRING event). + * There must be at least one RIL_UNSOL_CALL_RING at the beginning + * of a call and sending multiple is optional. If the system property + * ro.telephony.call_ring.multiple is false then the upper layers + * will generate the multiple events internally. Otherwise the vendor + * ril must generate multiple RIL_UNSOL_CALL_RING if + * ro.telephony.call_ring.multiple is true or if it is absent. + * + * The rate of these events is controlled by ro.telephony.call_ring.delay + * and has a default value of 3000 (3 seconds) if absent. + * + * "data" is null for GSM + * "data" is const RIL_CDMA_SignalInfoRecord * if CDMA + */ +#define RIL_UNSOL_CALL_RING 1018 + +/** + * RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED + * + * Indicates that SIM state changes. + * + * Callee will invoke RIL_REQUEST_GET_SIM_STATUS on main thread + + * "data" is null + */ +#define RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED 1019 + +/** + * RIL_UNSOL_RESPONSE_CDMA_NEW_SMS + * + * Called when new CDMA SMS is received + * + * "data" is const RIL_CDMA_SMS_Message * + * + * Callee will subsequently confirm the receipt of the SMS with + * a RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE + * + * No new RIL_UNSOL_RESPONSE_CDMA_NEW_SMS should be sent until + * RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE has been received + * + */ +#define RIL_UNSOL_RESPONSE_CDMA_NEW_SMS 1020 + +/** + * RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS + * + * Called when new Broadcast SMS is received + * + * "data" can be one of the following: + * If received from GSM network, "data" is const char of 88 bytes + * which indicates each page of a CBS Message sent to the MS by the + * BTS as coded in 3GPP 23.041 Section 9.4.1.2. + * If received from UMTS network, "data" is const char of 90 up to 1252 + * bytes which contain between 1 and 15 CBS Message pages sent as one + * packet to the MS by the BTS as coded in 3GPP 23.041 Section 9.4.2.2. + * + */ +#define RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS 1021 + +/** + * RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL + * + * Indicates that SMS storage on the RUIM is full. Messages + * cannot be saved on the RUIM until space is freed. + * + * "data" is null + * + */ +#define RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL 1022 + +/** + * RIL_UNSOL_RESTRICTED_STATE_CHANGED + * + * Indicates a restricted state change (eg, for Domain Specific Access Control). + * + * Radio need send this msg after radio off/on cycle no matter it is changed or not. + * + * "data" is an int * + * ((int *)data)[0] contains a bitmask of RIL_RESTRICTED_STATE_* values. + */ +#define RIL_UNSOL_RESTRICTED_STATE_CHANGED 1023 + +/** + * RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE + * + * Indicates that the radio system selection module has + * autonomously entered emergency callback mode. + * + * "data" is null + * + */ +#define RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE 1024 + +/** + * RIL_UNSOL_CDMA_CALL_WAITING + * + * Called when CDMA radio receives a call waiting indication. + * + * "data" is const RIL_CDMA_CallWaiting * + * + */ +#define RIL_UNSOL_CDMA_CALL_WAITING 1025 + +/** + * RIL_UNSOL_CDMA_OTA_PROVISION_STATUS + * + * Called when CDMA radio receives an update of the progress of an + * OTASP/OTAPA call. + * + * "data" is const int * + * For CDMA this is an integer OTASP/OTAPA status listed in + * RIL_CDMA_OTA_ProvisionStatus. + * + */ +#define RIL_UNSOL_CDMA_OTA_PROVISION_STATUS 1026 + +/** + * RIL_UNSOL_CDMA_INFO_REC + * + * Called when CDMA radio receives one or more info recs. + * + * "data" is const RIL_CDMA_InformationRecords * + * + */ +#define RIL_UNSOL_CDMA_INFO_REC 1027 + +/** + * RIL_UNSOL_OEM_HOOK_RAW + * + * This is for OEM specific use. + * + * "data" is a byte[] + */ +#define RIL_UNSOL_OEM_HOOK_RAW 1028 + +/** + * RIL_UNSOL_RINGBACK_TONE + * + * Indicates that nework doesn't have in-band information, need to + * play out-band tone. + * + * "data" is an int * + * ((int *)data)[0] == 0 for stop play ringback tone. + * ((int *)data)[0] == 1 for start play ringback tone. + */ +#define RIL_UNSOL_RINGBACK_TONE 1029 + +/** + * RIL_UNSOL_RESEND_INCALL_MUTE + * + * Indicates that framework/application need reset the uplink mute state. + * + * There may be situations where the mute state becomes out of sync + * between the application and device in some GSM infrastructures. + * + * "data" is null + */ +#define RIL_UNSOL_RESEND_INCALL_MUTE 1030 + +/** + * RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED + * + * Called when CDMA subscription source changed. + * + * "data" is int * + * ((int *)data)[0] is == RIL_CdmaSubscriptionSource + */ +#define RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED 1031 + +/** + * RIL_UNSOL_CDMA_PRL_CHANGED + * + * Called when PRL (preferred roaming list) changes. + * + * "data" is int * + * ((int *)data)[0] is PRL_VERSION as would be returned by RIL_REQUEST_CDMA_SUBSCRIPTION + */ +#define RIL_UNSOL_CDMA_PRL_CHANGED 1032 + +/** + * RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE + * + * Called when Emergency Callback Mode Ends + * + * Indicates that the radio system selection module has + * proactively exited emergency callback mode. + * + * "data" is NULL + * + */ +#define RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE 1033 + +/** + * RIL_UNSOL_RIL_CONNECTED + * + * Called the ril connects and returns the version + * + * "data" is int * + * ((int *)data)[0] is RIL_VERSION + */ +#define RIL_UNSOL_RIL_CONNECTED 1034 + +/** + * RIL_UNSOL_VOICE_RADIO_TECH_CHANGED + * + * Indicates that voice technology has changed. Contains new radio technology + * as a data in the message. + * + * "data" is int * + * ((int *)data)[0] is of type const RIL_RadioTechnology + * + */ +#define RIL_UNSOL_VOICE_RADIO_TECH_CHANGED 1035 + +/** + * RIL_UNSOL_CELL_INFO_LIST + * + * Same information as returned by RIL_REQUEST_GET_CELL_INFO_LIST, but returned + * at the rate no greater than specified by RIL_REQUEST_SET_UNSOL_CELL_INFO_RATE. + * + * "data" is NULL + * + * "response" is an array of RIL_CellInfo. + */ +#define RIL_UNSOL_CELL_INFO_LIST 1036 + +/* SAMSUNG RESPONSE */ +#define SAMSUNG_UNSOL_RESPONSE_BASE 11000 + +#define RIL_UNSOL_RELEASE_COMPLETE_MESSAGE 11001 +#define RIL_UNSOL_STK_SEND_SMS_RESULT 11002 +#define RIL_UNSOL_STK_CALL_CONTROL_RESULT 11003 +#define RIL_UNSOL_DUN_CALL_STATUS 11004 + +#define RIL_UNSOL_O2_HOME_ZONE_INFO 11007 +#define RIL_UNSOL_DEVICE_READY_NOTI 11008 +#define RIL_UNSOL_GPS_NOTI 11009 +#define RIL_UNSOL_AM 11010 +#define RIL_UNSOL_DUN_PIN_CONTROL_SIGNAL 11011 +#define RIL_UNSOL_DATA_SUSPEND_RESUME 11012 +#define RIL_UNSOL_SAP 11013 + +#define RIL_UNSOL_SIM_SMS_STORAGE_AVAILALE 11015 +#define RIL_UNSOL_HSDPA_STATE_CHANGED 11016 +#define RIL_UNSOL_WB_AMR_STATE 11017 +#define RIL_UNSOL_TWO_MIC_STATE 11018 +#define RIL_UNSOL_DHA_STATE 11019 +#define RIL_UNSOL_UART 11020 +#define RIL_UNSOL_RESPONSE_HANDOVER 11021 +#define RIL_UNSOL_IPV6_ADDR 11022 +#define RIL_UNSOL_NWK_INIT_DISC_REQUEST 11023 +#define RIL_UNSOL_RTS_INDICATION 11024 +#define RIL_UNSOL_OMADM_SEND_DATA 11025 +#define RIL_UNSOL_DUN 11026 +#define RIL_UNSOL_SYSTEM_REBOOT 11027 +#define RIL_UNSOL_VOICE_PRIVACY_CHANGED 11028 +#define RIL_UNSOL_UTS_GETSMSCOUNT 11029 +#define RIL_UNSOL_UTS_GETSMSMSG 11030 +#define RIL_UNSOL_UTS_GET_UNREAD_SMS_STATUS 11031 +#define RIL_UNSOL_MIP_CONNECT_STATUS 11032 + +/***********************************************************************/ + + +/** + * RIL_Request Function pointer + * + * @param request is one of RIL_REQUEST_* + * @param data is pointer to data defined for that RIL_REQUEST_* + * data is owned by caller, and should not be modified or freed by callee + * @param t should be used in subsequent call to RIL_onResponse + * @param datalen the length of data + * + */ +typedef void (*RIL_RequestFunc) (int request, void *data, + size_t datalen, RIL_Token t); + +/** + * This function should return the current radio state synchronously + */ +typedef RIL_RadioState (*RIL_RadioStateRequest)(); + +/** + * This function returns "1" if the specified RIL_REQUEST code is + * supported and 0 if it is not + * + * @param requestCode is one of RIL_REQUEST codes + */ + +typedef int (*RIL_Supports)(int requestCode); + +/** + * This function is called from a separate thread--not the + * thread that calls RIL_RequestFunc--and indicates that a pending + * request should be cancelled. + * + * On cancel, the callee should do its best to abandon the request and + * call RIL_onRequestComplete with RIL_Errno CANCELLED at some later point. + * + * Subsequent calls to RIL_onRequestComplete for this request with + * other results will be tolerated but ignored. (That is, it is valid + * to ignore the cancellation request) + * + * RIL_Cancel calls should return immediately, and not wait for cancellation + * + * Please see ITU v.250 5.6.1 for how one might implement this on a TS 27.007 + * interface + * + * @param t token wants to be canceled + */ + +typedef void (*RIL_Cancel)(RIL_Token t); + +typedef void (*RIL_TimedCallback) (void *param); + +/** + * Return a version string for your RIL implementation + */ +typedef const char * (*RIL_GetVersion) (void); + +typedef struct { + int version; /* set to RIL_VERSION */ + RIL_RequestFunc onRequest; + RIL_RadioStateRequest onStateRequest; + RIL_Supports supports; + RIL_Cancel onCancel; + RIL_GetVersion getVersion; +} RIL_RadioFunctions; + +#ifdef RIL_SHLIB +struct RIL_Env { + /** + * "t" is parameter passed in on previous call to RIL_Notification + * routine. + * + * If "e" != SUCCESS, then response can be null/is ignored + * + * "response" is owned by caller, and should not be modified or + * freed by callee + * + * RIL_onRequestComplete will return as soon as possible + */ + void (*OnRequestComplete)(RIL_Token t, RIL_Errno e, + void *response, size_t responselen); + + /** + * "unsolResponse" is one of RIL_UNSOL_RESPONSE_* + * "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_* + * + * "data" is owned by caller, and should not be modified or freed by callee + */ + + void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, + size_t datalen); + + /** + * Call user-specifed "callback" function on on the same thread that + * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies + * a relative time value at which the callback is invoked. If relativeTime is + * NULL or points to a 0-filled structure, the callback will be invoked as + * soon as possible + */ + + void (*RequestTimedCallback) (RIL_TimedCallback callback, + void *param, const struct timeval *relativeTime); +}; + + +/** + * RIL implementations must defined RIL_Init + * argc and argv will be command line arguments intended for the RIL implementation + * Return NULL on error + * + * @param env is environment point defined as RIL_Env + * @param argc number of arguments + * @param argv list fo arguments + * + */ +const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv); + +#else /* RIL_SHLIB */ + +/** + * Call this once at startup to register notification routine + * + * @param callbacks user-specifed callback function + */ +void RIL_register (const RIL_RadioFunctions *callbacks); + + +/** + * + * RIL_onRequestComplete will return as soon as possible + * + * @param t is parameter passed in on previous call to RIL_Notification + * routine. + * @param e error code + * if "e" != SUCCESS, then response can be null/is ignored + * @param response is owned by caller, and should not be modified or + * freed by callee + * @param responselen the length of response in byte + */ +void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, + void *response, size_t responselen); + +/** + * @param unsolResponse is one of RIL_UNSOL_RESPONSE_* + * @param data is pointer to data defined for that RIL_UNSOL_RESPONSE_* + * "data" is owned by caller, and should not be modified or freed by callee + * @param datalen the length of data in byte + */ + +void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, + size_t datalen); + + +/** + * Call user-specifed "callback" function on on the same thread that + * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies + * a relative time value at which the callback is invoked. If relativeTime is + * NULL or points to a 0-filled structure, the callback will be invoked as + * soon as possible + * + * @param callback user-specifed callback function + * @param param parameter list + * @param relativeTime a relative time value at which the callback is invoked + */ + +void RIL_requestTimedCallback (RIL_TimedCallback callback, + void *param, const struct timeval *relativeTime); + + +#endif /* RIL_SHLIB */ + +#ifdef __cplusplus +} +#endif + +#endif /*ANDROID_RIL_H*/ diff --git a/irda/Android.mk b/irda/Android.mk new file mode 100644 index 0000000..1659626 --- /dev/null +++ b/irda/Android.mk @@ -0,0 +1,13 @@ +LOCAL_PATH := $(call my-dir) + +# HAL module implemenation stored in +# hw/..so +include $(CLEAR_VARS) + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware libdl +LOCAL_SRC_FILES := irda.c +LOCAL_MODULE:= irda.exynos4 +LOCAL_MODULE_TAGS := optional +include $(BUILD_SHARED_LIBRARY) diff --git a/irda/irda.c b/irda/irda.c new file mode 100644 index 0000000..0068685 --- /dev/null +++ b/irda/irda.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2013 Cyanogenmod 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 + +#define LOG_TAG "irda" +#include +#include +#include +#include +#include +#include +#include + +#define IRDA_DEBUG 1 + +int fd = 0; + +void irda_send_ircode(char* buffer, int length) +{ + int retval; + + retval = write(fd, buffer, length); + + return; +} + +static int open_irda(const struct hw_module_t* module, char const* name, + struct hw_device_t** device) +{ + struct irda_device_t *dev = malloc(sizeof(struct irda_device_t)); + memset(dev, 0, sizeof(*dev)); + + dev->common.tag = HARDWARE_DEVICE_TAG; + dev->common.version = 0; + dev->common.module = (struct hw_module_t*)module; + dev->send_ircode = irda_send_ircode; + + *device = (struct hw_device_t*) dev; + + fd = open("/sys/class/sec/sec_ir/ir_send", O_RDWR); + if(fd < 0) { + ALOGE("Unable to open IR device: %d - %s",errno,strerror(errno)); + return fd; + } + + return 0; +} + +static struct hw_module_methods_t irda_module_methods = { + .open = open_irda +}; + +struct hw_module_t HAL_MODULE_INFO_SYM = { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = 1, + .hal_api_version = 0, + .id = IRDA_HARDWARE_MODULE_ID, + .name = "Irda HW Module", + .author = "The CyanogenMod Project", + .methods = &irda_module_methods, +}; diff --git a/libsensors/AccelSensor.cpp b/libsensors/AccelSensor.cpp new file mode 100644 index 0000000..3ab5e2e --- /dev/null +++ b/libsensors/AccelSensor.cpp @@ -0,0 +1,176 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + + +#include "AccelSensor.h" + + +/*****************************************************************************/ +AccelSensor::AccelSensor() + : SensorBase(NULL, "accelerometer"), + mEnabled(0), + + mInputReader(4), + mHasPendingEvent(false) +{ + // ALOGD("AccelSensor::AccelSensor()"); + mPendingEvent.version = sizeof(sensors_event_t); + mPendingEvent.sensor = ID_A; + mPendingEvent.type = SENSOR_TYPE_ACCELEROMETER; + memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); + + // ALOGD("AccelSensor::AccelSensor() open data_fd"); + + if (data_fd) { + strcpy(input_sysfs_path, "/sys/class/input/"); + strcat(input_sysfs_path, input_name); + strcat(input_sysfs_path, "/device/"); + input_sysfs_path_len = strlen(input_sysfs_path); + + //enable(0, 1); + } + // ALOGE("AccelSensor: sysfs: %s",input_sysfs_path); +} + +AccelSensor::~AccelSensor() { + + // ALOGD("AccelSensor::~AccelSensor()"); + if (mEnabled) { + enable(0, 0); + } +} + + + +int AccelSensor::enable(int32_t, int en) { + + + // ALOGD("AccelSensor::~enable(0, %d)", en); + int flags = en ? 1 : 0; + if (flags != mEnabled) { + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); + // ALOGD("AccelSensor::~enable(0, %d) open %s",en, input_sysfs_path); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + // ALOGD("AccelSensor::~enable(0, %d) opened %s",en, input_sysfs_path); + char buf[2]; + int err; + buf[1] = 0; + if (flags) { + buf[0] = '1'; + } else { + buf[0] = '0'; + } + err = write(fd, buf, sizeof(buf)); + close(fd); + mEnabled = flags; + //setInitialState(); + return 0; + } + return -1; + } + return 0; +} + + +bool AccelSensor::hasPendingEvents() const { + /* FIXME probably here should be returning mEnabled but instead + mHasPendingEvents. It does not work, so we cheat.*/ + //ALOGD("AccelSensor::~hasPendingEvents %d", mHasPendingEvent ? 1 : 0 ); + return mHasPendingEvent; +} + + +int AccelSensor::setDelay(int32_t handle, int64_t ns) +{ + // ALOGD("AccelSensor::~setDelay(%d, %lld)", handle, ns); + + int fd; + + if (ns < 10000000) { + ns = 10000000; // Minimum on stock + } + + strcpy(&input_sysfs_path[input_sysfs_path_len], "delay"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[80]; + sprintf(buf, "%lld", ns / 10000000 * 10); // Some flooring to match stock value + write(fd, buf, strlen(buf)+1); + close(fd); + return 0; + } + return -1; +} + + +int AccelSensor::readEvents(sensors_event_t* data, int count) +{ + //ALOGD("AccelSensor::~readEvents() %d", count); + if (count < 1) + return -EINVAL; + + if (mHasPendingEvent) { + mHasPendingEvent = false; + mPendingEvent.timestamp = getTimestamp(); + *data = mPendingEvent; + return mEnabled ? 1 : 0; + } + + ssize_t n = mInputReader.fill(data_fd); + if (n < 0) + return n; + + int numEventReceived = 0; + input_event const* event; + + while (count && mInputReader.readEvent(&event)) { + int type = event->type; + if (type == EV_ABS) { + float value = event->value; + if (event->code == EVENT_TYPE_ACCEL_X) { + mPendingEvent.acceleration.x = value * CONVERT_A_X; + } else if (event->code == EVENT_TYPE_ACCEL_Y) { + mPendingEvent.acceleration.y = value * CONVERT_A_Y; + } else if (event->code == EVENT_TYPE_ACCEL_Z) { + mPendingEvent.acceleration.z = value * CONVERT_A_Z; + } + } else if (type == EV_SYN) { + mPendingEvent.timestamp = timevalToNano(event->time); + if (mEnabled) { + *data++ = mPendingEvent; + count--; + numEventReceived++; + } + } else { + ALOGE("AccelSensor: unknown event (type=%d, code=%d)", + type, event->code); + } + mInputReader.next(); + } + return numEventReceived++; + +} diff --git a/libsensors/AccelSensor.h b/libsensors/AccelSensor.h new file mode 100644 index 0000000..e87c3ec --- /dev/null +++ b/libsensors/AccelSensor.h @@ -0,0 +1,69 @@ +/* + * 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 ANDROID_SMB380_SENSOR_H +#define ANDROID_SMB380_SENSOR_H + +#include +#include +#include +#include + +#include "sensors.h" +#include "SensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + + +struct smb380acc_t { + short x, /**< holds x-axis acceleration data sign extended. Range -512 to 511. */ + y, /**< holds y-axis acceleration data sign extended. Range -512 to 511. */ + z; /**< holds z-axis acceleration data sign extended. Range -512 to 511. */ +} ; + +/* smb ioctl command label */ +#define IOCTL_SMB_GET_ACC_VALUE 0 +#define DCM_IOC_MAGIC 's' +#define IOC_SET_ACCELEROMETER _IO (DCM_IOC_MAGIC, 0x64) +#define BMA150_CALIBRATION _IOWR(DCM_IOC_MAGIC,48,short) + +#define SMB_POWER_OFF 0 +#define SMB_POWER_ON 1 + +struct input_event; + +class AccelSensor : public SensorBase { + int mEnabled; + InputEventCircularReader mInputReader; + sensors_event_t mPendingEvent; + bool mHasPendingEvent; + char input_sysfs_path[PATH_MAX]; + int input_sysfs_path_len; + + +public: + AccelSensor(); + virtual ~AccelSensor(); + virtual int readEvents(sensors_event_t* data, int count); + virtual bool hasPendingEvents() const; + virtual int setDelay(int32_t handle, int64_t ns); + virtual int enable(int32_t handle, int enabled); +}; + +/*****************************************************************************/ + +#endif // ANDROID_GYRO_SENSOR_H diff --git a/libsensors/Android.mk b/libsensors/Android.mk new file mode 100644 index 0000000..1542efe --- /dev/null +++ b/libsensors/Android.mk @@ -0,0 +1,47 @@ +# 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) + +ifneq ($(TARGET_SIMULATOR),true) + +# HAL module implemenation, not prelinked, and stored in +# hw/..so +include $(CLEAR_VARS) + +LOCAL_MODULE := sensors.$(TARGET_BOOTLOADER_BOARD_NAME) + +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw + +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -DLOG_TAG=\"Sensors\" + +LOCAL_SRC_FILES := \ + sensors.cpp \ + SensorBase.cpp \ + LightSensor.cpp \ + ProximitySensor.cpp \ + AccelSensor.cpp \ + CompassSensor.cpp \ + OrientationSensor.cpp \ + InputEventReader.cpp + +LOCAL_SHARED_LIBRARIES := liblog libcutils libdl +LOCAL_PRELINK_MODULE := false + +include $(BUILD_SHARED_LIBRARY) + +endif + diff --git a/libsensors/CompassSensor.cpp b/libsensors/CompassSensor.cpp new file mode 100644 index 0000000..39daa81 --- /dev/null +++ b/libsensors/CompassSensor.cpp @@ -0,0 +1,190 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + + +#include "CompassSensor.h" + + +/*****************************************************************************/ +CompassSensor::CompassSensor() + : SensorBase(NULL, "geomagnetic"), + //mEnabled(0), + mInputReader(4), + mHasPendingEvent(false) +{ + //ALOGD("CompassSensor::CompassSensor()"); + mPendingEvent.version = sizeof(sensors_event_t); + mPendingEvent.sensor = ID_M; + mPendingEvent.type = SENSOR_TYPE_MAGNETIC_FIELD; + mPendingEvent.magnetic.status = SENSOR_STATUS_ACCURACY_HIGH; + + + memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); + + // ALOGD("CompassSensor::CompassSensor() open data_fd"); + + if (data_fd) { + strcpy(input_sysfs_path, "/sys/class/input/"); + strcat(input_sysfs_path, input_name); + strcat(input_sysfs_path, "/device/"); + input_sysfs_path_len = strlen(input_sysfs_path); + + //enable(0, 1); + } + + // ALOGE("MagneticSensor: sysfs: %s",input_sysfs_path); +} + +CompassSensor::~CompassSensor() { + + // ALOGD("CompassSensor::~CompassSensor()"); + if (mEnabled) { + enable(0, 0); + } +} + + + +int CompassSensor::enable(int32_t, int en) { + + + // ALOGD("CompassSensor::~enable(0, %d)", en); + int flags = en ? 1 : 0; + if (flags != mEnabled) { + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); + //ALOGD("CompassSensor::~enable(0, %d) open %s",en, input_sysfs_path); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + // ALOGD("CompassSensor::~enable(0, %d) opened %s",en, input_sysfs_path); + char buf[2]; + int err; + buf[1] = 0; + if (flags) { + buf[0] = '1'; + } else { + buf[0] = '0'; + } + err = write(fd, buf, sizeof(buf)); + close(fd); + mEnabled = flags; + return 0; + } + return -1; + } + return 0; +} + + +bool CompassSensor::hasPendingEvents() const { + /* FIXME probably here should be returning mEnabled but instead + mHasPendingEvents. It does not work, so we cheat.*/ + //ALOGD("CompassSensor::~hasPendingEvents %d", mHasPendingEvent ? 1 : 0 ); + return mHasPendingEvent; +} + + +int CompassSensor::setDelay(int32_t handle, int64_t ns) +{ + int fd; + int val; + + // Kernel driver only support specific values + if (ns < 20000000L) { + val = 1; + } else if (ns < 60000000L) { + val = 20; + } else if (ns < 200000000L) { + val = 60; + } else if (ns < 1000000000L) { + val = 200; + } else { + val = 1000; + } + + // ALOGD("CompassSensor::~setDelay(%d, %lld) val = %d", handle, ns, val); + + strcpy(&input_sysfs_path[input_sysfs_path_len], "delay"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[80]; + sprintf(buf, "%d", val); + write(fd, buf, strlen(buf)+1); + close(fd); + return 0; + } + return -1; +} + + +int CompassSensor::readEvents(sensors_event_t* data, int count) +{ + //ALOGD("CompassSensor::~readEvents() %d", count); + if (count < 1) + return -EINVAL; + + if (mHasPendingEvent) { + mHasPendingEvent = false; + mPendingEvent.timestamp = getTimestamp(); + *data = mPendingEvent; + return mEnabled ? 1 : 0; + } + + ssize_t n = mInputReader.fill(data_fd); + if (n < 0) + return n; + + int numEventReceived = 0; + input_event const* event; + + while (count && mInputReader.readEvent(&event)) { + int type = event->type; + if (type == EV_ABS) { + float value = event->value; + if (event->code == EVENT_TYPE_MAGV_X) { + mPendingEvent.magnetic.x = (float)value / 1000.0f; + } else if (event->code == EVENT_TYPE_MAGV_Y) { + mPendingEvent.magnetic.y = (float)value / 1000.0f; + } else if (event->code == EVENT_TYPE_MAGV_Z) { + mPendingEvent.magnetic.z = (float)value / 1000.0f; + } + } else if (type == EV_SYN) { + mPendingEvent.timestamp = timevalToNano(event->time); + if (mEnabled) { + *data++ = mPendingEvent; + count--; + numEventReceived++; + } + } else { + ALOGE("CompassSensor: unknown event (type=%d, code=%d)", + type, event->code); + } + mInputReader.next(); + } + + //ALOGD("CompassSensor::~readEvents() numEventReceived = %d", numEventReceived); + return numEventReceived++; + +} diff --git a/libsensors/CompassSensor.h b/libsensors/CompassSensor.h new file mode 100644 index 0000000..9b34f9d --- /dev/null +++ b/libsensors/CompassSensor.h @@ -0,0 +1,54 @@ +/* + * 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 ANDROID_COMPASS_SENSOR_H +#define ANDROID_COMPASS_SENSOR_H + +#include +#include +#include +#include + +#include "sensors.h" +#include "SensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + + +struct input_event; + +class CompassSensor : public SensorBase { + int mEnabled; + InputEventCircularReader mInputReader; + sensors_event_t mPendingEvent; + bool mHasPendingEvent; + char input_sysfs_path[PATH_MAX]; + int input_sysfs_path_len; + + +public: + CompassSensor(); + virtual ~CompassSensor(); + virtual int readEvents(sensors_event_t* data, int count); + virtual bool hasPendingEvents() const; + virtual int setDelay(int32_t handle, int64_t ns); + virtual int enable(int32_t handle, int enabled); +}; + +/*****************************************************************************/ + +#endif // ANDROID_GYRO_SENSOR_H diff --git a/libsensors/InputEventReader.cpp b/libsensors/InputEventReader.cpp new file mode 100644 index 0000000..1014f29 --- /dev/null +++ b/libsensors/InputEventReader.cpp @@ -0,0 +1,88 @@ +/* + * 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 +#include +#include +#include + +#include +#include + +#include + +#include + +#include "InputEventReader.h" + +/*****************************************************************************/ + +struct input_event; + +InputEventCircularReader::InputEventCircularReader(size_t numEvents) + : mBuffer(new input_event[numEvents * 2]), + mBufferEnd(mBuffer + numEvents), + mHead(mBuffer), + mCurr(mBuffer), + mFreeSpace(numEvents) +{ +} + +InputEventCircularReader::~InputEventCircularReader() +{ + delete [] mBuffer; +} + +ssize_t InputEventCircularReader::fill(int fd) +{ + size_t numEventsRead = 0; + if (mFreeSpace) { + const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event)); + if (nread<0 || nread % sizeof(input_event)) { + // we got a partial event!! + return nread<0 ? -errno : -EINVAL; + } + + numEventsRead = nread / sizeof(input_event); + if (numEventsRead) { + mHead += numEventsRead; + mFreeSpace -= numEventsRead; + if (mHead > mBufferEnd) { + size_t s = mHead - mBufferEnd; + memcpy(mBuffer, mBufferEnd, s * sizeof(input_event)); + mHead = mBuffer + s; + } + } + } + + return numEventsRead; +} + +ssize_t InputEventCircularReader::readEvent(input_event const** events) +{ + *events = mCurr; + ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace; + return available ? 1 : 0; +} + +void InputEventCircularReader::next() +{ + mCurr++; + mFreeSpace++; + if (mCurr >= mBufferEnd) { + mCurr = mBuffer; + } +} diff --git a/libsensors/InputEventReader.h b/libsensors/InputEventReader.h new file mode 100644 index 0000000..180aade --- /dev/null +++ b/libsensors/InputEventReader.h @@ -0,0 +1,47 @@ +/* + * 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 ANDROID_INPUT_EVENT_READER_H +#define ANDROID_INPUT_EVENT_READER_H + +#include +#include +#include +#include + +/*****************************************************************************/ + +struct input_event; + +class InputEventCircularReader +{ + struct input_event* const mBuffer; + struct input_event* const mBufferEnd; + struct input_event* mHead; + struct input_event* mCurr; + ssize_t mFreeSpace; + +public: + InputEventCircularReader(size_t numEvents); + ~InputEventCircularReader(); + ssize_t fill(int fd); + ssize_t readEvent(input_event const** events); + void next(); +}; + +/*****************************************************************************/ + +#endif // ANDROID_INPUT_EVENT_READER_H diff --git a/libsensors/LightSensor.cpp b/libsensors/LightSensor.cpp new file mode 100644 index 0000000..e931e2e --- /dev/null +++ b/libsensors/LightSensor.cpp @@ -0,0 +1,145 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "LightSensor.h" + +/*****************************************************************************/ + +LightSensor::LightSensor() + : SensorBase(NULL, "light_sensor"), + mEnabled(0), + mInputReader(4), + mHasPendingEvent(false) +{ + mPendingEvent.version = sizeof(sensors_event_t); + mPendingEvent.sensor = ID_L; + mPendingEvent.type = SENSOR_TYPE_LIGHT; + memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); + + if (data_fd) { + strcpy(input_sysfs_path, "/sys/class/input/"); + strcat(input_sysfs_path, input_name); + strcat(input_sysfs_path, "/device/"); + input_sysfs_path_len = strlen(input_sysfs_path); + enable(0, 1); + } + // ALOGE("LightSensor: sysfs: %s",input_sysfs_path); +} + +LightSensor::~LightSensor() { + if (mEnabled) { + enable(0, 0); + } +} + +int LightSensor::setDelay(int32_t handle, int64_t ns) +{ + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "poll_delay"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[80]; + sprintf(buf, "%lld", ns); + write(fd, buf, strlen(buf)+1); + close(fd); + return 0; + } + return -1; +} + +int LightSensor::enable(int32_t handle, int en) +{ + int flags = en ? 1 : 0; + if (flags != mEnabled) { + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[2]; + int err; + buf[1] = 0; + if (flags) { + buf[0] = '1'; + } else { + buf[0] = '0'; + } + err = write(fd, buf, sizeof(buf)); + close(fd); + mEnabled = flags; + return 0; + } + return -1; + } + return 0; +} + +bool LightSensor::hasPendingEvents() const { + return mHasPendingEvent; +} + +int LightSensor::readEvents(sensors_event_t* data, int count) +{ + if (count < 1) + return -EINVAL; + + if (mHasPendingEvent) { + mHasPendingEvent = false; + mPendingEvent.timestamp = getTimestamp(); + *data = mPendingEvent; + return mEnabled ? 1 : 0; + } + + ssize_t n = mInputReader.fill(data_fd); + if (n < 0) + return n; + + int numEventReceived = 0; + input_event const* event; + + while (count && mInputReader.readEvent(&event)) { + int type = event->type; + if (type == EV_REL) { + // Convert adc value to lux assuming: + // I = 10 * log(Ev) uA + // R = 47kOhm + // Max adc value 4095 = 3.3V + // 1/4 of light reaches sensor + mPendingEvent.light = event->value; + } else if (type == EV_SYN) { + mPendingEvent.timestamp = timevalToNano(event->time); + if (mEnabled) { + *data++ = mPendingEvent; + count--; + numEventReceived++; + } + } else { + ALOGE("LightSensor: unknown event (type=%d, code=%d)", + type, event->code); + } + mInputReader.next(); + } + + return numEventReceived; +} diff --git a/libsensors/LightSensor.h b/libsensors/LightSensor.h new file mode 100644 index 0000000..79e0ccf --- /dev/null +++ b/libsensors/LightSensor.h @@ -0,0 +1,54 @@ +/* + * 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 ANDROID_LIGHT_SENSOR_H +#define ANDROID_LIGHT_SENSOR_H + +#include +#include +#include +#include + +#include "sensors.h" +#include "SensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + +struct input_event; + +class LightSensor : public SensorBase { + int mEnabled; + InputEventCircularReader mInputReader; + sensors_event_t mPendingEvent; + bool mHasPendingEvent; + char input_sysfs_path[PATH_MAX]; + int input_sysfs_path_len; + + int setInitialState(); + +public: + LightSensor(); + virtual ~LightSensor(); + virtual int readEvents(sensors_event_t* data, int count); + virtual bool hasPendingEvents() const; + virtual int setDelay(int32_t handle, int64_t ns); + virtual int enable(int32_t handle, int enabled); +}; + +/*****************************************************************************/ + +#endif // ANDROID_LIGHT_SENSOR_H diff --git a/libsensors/OrientationSensor.cpp b/libsensors/OrientationSensor.cpp new file mode 100644 index 0000000..0ca6085 --- /dev/null +++ b/libsensors/OrientationSensor.cpp @@ -0,0 +1,184 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "OrientationSensor.h" + + +/*****************************************************************************/ +OrientationSensor::OrientationSensor() + : SensorBase(NULL, "orientation"), + mEnabled(0), + mInputReader(4), + mHasPendingEvent(false) +{ + // ALOGD("OrientationSensor::OrientationSensor()"); + mPendingEvent.version = sizeof(sensors_event_t); + mPendingEvent.sensor = ID_O; + mPendingEvent.type = SENSOR_TYPE_ORIENTATION; + memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); + + // ALOGD("OrientationSensor::OrientationSensor() open data_fd"); + + if (data_fd) { + strcpy(input_sysfs_path, "/sys/class/input/"); + strcat(input_sysfs_path, input_name); + strcat(input_sysfs_path, "/device/"); + input_sysfs_path_len = strlen(input_sysfs_path); + + // enable(0, 1); + //ALOGE("OrientationSensor: sysfs: %s",input_sysfs_path); + } +} + +OrientationSensor::~OrientationSensor() { + + // ALOGD("OrientationSensor::~OrientationSensor()"); + if (mEnabled) { + enable(0, 0); + } +} + + +int OrientationSensor::enable(int32_t, int en) { + + + // ALOGD("OrientationSensor::~enable(0, %d)", en); + int flags = en ? 1 : 0; + if (flags != mEnabled) { + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); + //ALOGD("OrientationSensor::~enable(0, %d) open %s",en, input_sysfs_path); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + // ALOGD("OrientationSensor::~enable(0, %d) opened %s",en, input_sysfs_path); + char buf[2]; + int err; + buf[1] = 0; + if (flags) { + buf[0] = '1'; + } else { + buf[0] = '0'; + } + err = write(fd, buf, sizeof(buf)); + close(fd); + mEnabled = flags; + //setInitialState(); + + /* Since the migration to 3.0 kernel, orientationd doesn't poll + * the enabled state properly, so start it when it's enabled and + * stop it when we're done using it. + */ + property_set(mEnabled ? "ctl.start" : "ctl.stop", "orientationd"); + return 0; + } + return -1; + } + return 0; +} + + +bool OrientationSensor::hasPendingEvents() const { + /* FIXME probably here should be returning mEnabled but instead + mHasPendingEvents. It does not work, so we cheat.*/ + //ALOGD("OrientationSensor::~hasPendingEvents %d", mHasPendingEvent ? 1 : 0 ); + return mHasPendingEvent; +} + + +int OrientationSensor::setDelay(int32_t handle, int64_t ns) +{ + //ALOGD("OrientationSensor::~setDelay(%d, %lld)", handle, ns); + + int fd; + + if (ns < 10000000) { + ns = 10000000; // Minimum on stock + } + + strcpy(&input_sysfs_path[input_sysfs_path_len], "delay"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[80]; + sprintf(buf, "%lld", ns / 10000000 * 10); // Some flooring to match stock value + write(fd, buf, strlen(buf)+1); + close(fd); + return 0; + } + return -1; +} + + +int OrientationSensor::readEvents(sensors_event_t* data, int count) +{ + //ALOGD("OrientationSensor::~readEvents() %d", count); + if (count < 1) + return -EINVAL; + + if (mHasPendingEvent) { + mHasPendingEvent = false; + mPendingEvent.timestamp = getTimestamp(); + *data = mPendingEvent; + return mEnabled ? 1 : 0; + } + + ssize_t n = mInputReader.fill(data_fd); + if (n < 0) + return n; + + int numEventReceived = 0; + input_event const* event; + + while (count && mInputReader.readEvent(&event)) { + int type = event->type; + if (type == EV_ABS) { + float value = event->value; + //ALOGD("OrientationSensor: event->code = %i",event->code); + if (event->code == EVENT_TYPE_YAW) { + mPendingEvent.orientation.azimuth = value * CONVERT_O_A; + } else if (event->code == EVENT_TYPE_PITCH) { + mPendingEvent.orientation.pitch = value * CONVERT_O_P; + } else if (event->code == EVENT_TYPE_ROLL) { + mPendingEvent.orientation.roll = value * CONVERT_O_R; + } + } else if (type == EV_SYN) { + mPendingEvent.timestamp = timevalToNano(event->time); + if (mEnabled) { + *data++ = mPendingEvent; + count--; + numEventReceived++; + } + } else { + ALOGE("OrientationSensor: unknown event (type=%d, code=%d)", + type, event->code); + } + mInputReader.next(); + } + + //ALOGD("OrientationSensor::~readEvents() numEventReceived = %d", numEventReceived); + return numEventReceived++; + +} diff --git a/libsensors/OrientationSensor.h b/libsensors/OrientationSensor.h new file mode 100644 index 0000000..7add75b --- /dev/null +++ b/libsensors/OrientationSensor.h @@ -0,0 +1,54 @@ +/* + * 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 ANDROID_ORIEN_SENSOR_H +#define ANDROID_ORIEN_SENSOR_H + +#include +#include +#include +#include + +#include "sensors.h" +#include "SensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + + +struct input_event; + +class OrientationSensor : public SensorBase { + int mEnabled; + InputEventCircularReader mInputReader; + sensors_event_t mPendingEvent; + bool mHasPendingEvent; + char input_sysfs_path[PATH_MAX]; + int input_sysfs_path_len; + + +public: + OrientationSensor(); + virtual ~OrientationSensor(); + virtual int readEvents(sensors_event_t* data, int count); + virtual bool hasPendingEvents() const; + virtual int setDelay(int32_t handle, int64_t ns); + virtual int enable(int32_t handle, int enabled); +}; + +/*****************************************************************************/ + +#endif // ANDROID_GYRO_SENSOR_H diff --git a/libsensors/ProximitySensor.cpp b/libsensors/ProximitySensor.cpp new file mode 100644 index 0000000..2f3604c --- /dev/null +++ b/libsensors/ProximitySensor.cpp @@ -0,0 +1,144 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include + +#include "ProximitySensor.h" + +/*****************************************************************************/ + +ProximitySensor::ProximitySensor() + : SensorBase(NULL, "proximity_sensor"), + mEnabled(0), + mInputReader(4), + mHasPendingEvent(false) +{ + mPendingEvent.version = sizeof(sensors_event_t); + mPendingEvent.sensor = ID_P; + mPendingEvent.type = SENSOR_TYPE_PROXIMITY; + memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); + + if (data_fd) { + strcpy(input_sysfs_path, "/sys/class/input/"); + strcat(input_sysfs_path, input_name); + strcat(input_sysfs_path, "/device/"); + input_sysfs_path_len = strlen(input_sysfs_path); + enable(0, 1); + } +} + +ProximitySensor::~ProximitySensor() { + if (mEnabled) { + enable(0, 0); + } +} + +int ProximitySensor::setInitialState() { + struct input_absinfo absinfo; + if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_PROXIMITY), &absinfo)) { + // make sure to report an event immediately + mHasPendingEvent = true; + mPendingEvent.distance = indexToValue(absinfo.value); + } + return 0; +} + +int ProximitySensor::enable(int32_t, int en) { + int flags = en ? 1 : 0; + if (flags != mEnabled) { + int fd; + strcpy(&input_sysfs_path[input_sysfs_path_len], "enable"); + fd = open(input_sysfs_path, O_RDWR); + if (fd >= 0) { + char buf[2]; + buf[1] = 0; + if (flags) { + buf[0] = '1'; + } else { + buf[0] = '0'; + } + write(fd, buf, sizeof(buf)); + close(fd); + mEnabled = flags; + setInitialState(); + return 0; + } + return -1; + } + return 0; +} + +bool ProximitySensor::hasPendingEvents() const { + return mHasPendingEvent; +} + +int ProximitySensor::readEvents(sensors_event_t* data, int count) +{ + if (count < 1) + return -EINVAL; + + if (mHasPendingEvent) { + mHasPendingEvent = false; + mPendingEvent.timestamp = getTimestamp(); + *data = mPendingEvent; + return mEnabled ? 1 : 0; + } + + ssize_t n = mInputReader.fill(data_fd); + if (n < 0) + return n; + + int numEventReceived = 0; + input_event const* event; + + while (count && mInputReader.readEvent(&event)) { + int type = event->type; + if (type == EV_ABS) { + if (event->code == EVENT_TYPE_PROXIMITY) { + if (event->value != -1) { + // FIXME: not sure why we're getting -1 sometimes + mPendingEvent.distance = indexToValue(event->value); + } + } + } else if (type == EV_SYN) { + mPendingEvent.timestamp = timevalToNano(event->time); + if (mEnabled) { + *data++ = mPendingEvent; + count--; + numEventReceived++; + } + } else { + ALOGE("ProximitySensor: unknown event (type=%d, code=%d)", + type, event->code); + } + mInputReader.next(); + } + + return numEventReceived; +} + +float ProximitySensor::indexToValue(size_t index) const +{ + return index * PROXIMITY_THRESHOLD_GP2A; +} diff --git a/libsensors/ProximitySensor.h b/libsensors/ProximitySensor.h new file mode 100644 index 0000000..08ea49c --- /dev/null +++ b/libsensors/ProximitySensor.h @@ -0,0 +1,54 @@ +/* + * 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 ANDROID_PROXIMITY_SENSOR_H +#define ANDROID_PROXIMITY_SENSOR_H + +#include +#include +#include +#include + +#include "sensors.h" +#include "SensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + +struct input_event; + +class ProximitySensor : public SensorBase { + int mEnabled; + InputEventCircularReader mInputReader; + sensors_event_t mPendingEvent; + bool mHasPendingEvent; + char input_sysfs_path[PATH_MAX]; + int input_sysfs_path_len; + + int setInitialState(); + float indexToValue(size_t index) const; + +public: + ProximitySensor(); + virtual ~ProximitySensor(); + virtual int readEvents(sensors_event_t* data, int count); + virtual bool hasPendingEvents() const; + virtual int enable(int32_t handle, int enabled); +}; + +/*****************************************************************************/ + +#endif // ANDROID_PROXIMITY_SENSOR_H diff --git a/libsensors/SensorBase.cpp b/libsensors/SensorBase.cpp new file mode 100644 index 0000000..79b1ee2 --- /dev/null +++ b/libsensors/SensorBase.cpp @@ -0,0 +1,128 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "SensorBase.h" + +/*****************************************************************************/ + +SensorBase::SensorBase( + const char* dev_name, + const char* data_name) + : dev_name(dev_name), data_name(data_name), + dev_fd(-1), data_fd(-1) +{ + if (data_name) { + data_fd = openInput(data_name); + } +} + +SensorBase::~SensorBase() { + if (data_fd >= 0) { + close(data_fd); + } + if (dev_fd >= 0) { + close(dev_fd); + } +} + +int SensorBase::open_device() { + if (dev_fd<0 && dev_name) { + dev_fd = open(dev_name, O_RDONLY); + ALOGE_IF(dev_fd<0, "Couldn't open %s (%s)", dev_name, strerror(errno)); + } + return 0; +} + +int SensorBase::close_device() { + if (dev_fd >= 0) { + close(dev_fd); + dev_fd = -1; + } + return 0; +} + +int SensorBase::getFd() const { + if (!data_name) { + return dev_fd; + } + return data_fd; +} + +int SensorBase::setDelay(int32_t handle, int64_t ns) { + return 0; +} + +bool SensorBase::hasPendingEvents() const { + return false; +} + +int64_t SensorBase::getTimestamp() { + struct timespec t; + t.tv_sec = t.tv_nsec = 0; + clock_gettime(CLOCK_MONOTONIC, &t); + return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec; +} + +int SensorBase::openInput(const char* inputName) { + int fd = -1; + const char *dirname = "/dev/input"; + char devname[PATH_MAX]; + char *filename; + DIR *dir; + struct dirent *de; + dir = opendir(dirname); + if(dir == NULL) + return -1; + strcpy(devname, dirname); + filename = devname + strlen(devname); + *filename++ = '/'; + while((de = readdir(dir))) { + if(de->d_name[0] == '.' && + (de->d_name[1] == '\0' || + (de->d_name[1] == '.' && de->d_name[2] == '\0'))) + continue; + strcpy(filename, de->d_name); + fd = open(devname, O_RDONLY); + if (fd>=0) { + char name[80]; + if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { + name[0] = '\0'; + } + if (!strcmp(name, inputName)) { + strcpy(input_name, filename); + break; + } else { + close(fd); + fd = -1; + } + } + } + closedir(dir); + ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName); + return fd; +} diff --git a/libsensors/SensorBase.h b/libsensors/SensorBase.h new file mode 100644 index 0000000..bb4d055 --- /dev/null +++ b/libsensors/SensorBase.h @@ -0,0 +1,65 @@ +/* + * 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 ANDROID_SENSOR_BASE_H +#define ANDROID_SENSOR_BASE_H + +#include +#include +#include +#include + + +/*****************************************************************************/ + +struct sensors_event_t; + +class SensorBase { +protected: + const char* dev_name; + const char* data_name; + char input_name[PATH_MAX]; + int dev_fd; + int data_fd; + + int openInput(const char* inputName); + static int64_t getTimestamp(); + + + static int64_t timevalToNano(timeval const& t) { + return t.tv_sec*1000000000LL + t.tv_usec*1000; + } + + int open_device(); + int close_device(); + +public: + SensorBase( + const char* dev_name, + const char* data_name); + + virtual ~SensorBase(); + + virtual int readEvents(sensors_event_t* data, int count) = 0; + virtual bool hasPendingEvents() const; + virtual int getFd() const; + virtual int setDelay(int32_t handle, int64_t ns); + virtual int enable(int32_t handle, int enabled) = 0; +}; + +/*****************************************************************************/ + +#endif // ANDROID_SENSOR_BASE_H diff --git a/libsensors/sensors.cpp b/libsensors/sensors.cpp new file mode 100644 index 0000000..a0194ef --- /dev/null +++ b/libsensors/sensors.cpp @@ -0,0 +1,374 @@ +/* + * 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. + */ + +#define LOG_TAG "Sensors" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#include +#include + +#include "sensors.h" + +#include "LightSensor.h" +#include "ProximitySensor.h" +//#include "BoschYamaha.h" +#include "AccelSensor.h" +#include "CompassSensor.h" +#include "OrientationSensor.h" + +/*****************************************************************************/ + +#define DELAY_OUT_TIME 0x7FFFFFFF + +#define LIGHT_SENSOR_POLLTIME 2000000000 + + +#define SENSORS_ACCELERATION (1<getFd(); + mPollFds[light].events = POLLIN; + mPollFds[light].revents = 0; + + mSensors[proximity] = new ProximitySensor(); + mPollFds[proximity].fd = mSensors[proximity]->getFd(); + mPollFds[proximity].events = POLLIN; + mPollFds[proximity].revents = 0; + + mSensors[bosch] = new AccelSensor(); + mPollFds[bosch].fd = mSensors[bosch]->getFd(); + mPollFds[bosch].events = POLLIN; + mPollFds[bosch].revents = 0; + + mSensors[yamaha] = new CompassSensor(); + mPollFds[yamaha].fd = mSensors[yamaha]->getFd(); + mPollFds[yamaha].events = POLLIN; + mPollFds[yamaha].revents = 0; + + mSensors[orientation] = new OrientationSensor(); + mPollFds[orientation].fd = mSensors[orientation]->getFd(); + mPollFds[orientation].events = POLLIN; + mPollFds[orientation].revents = 0; + + int wakeFds[2]; + int result = pipe(wakeFds); + ALOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno)); + fcntl(wakeFds[0], F_SETFL, O_NONBLOCK); + fcntl(wakeFds[1], F_SETFL, O_NONBLOCK); + mWritePipeFd = wakeFds[1]; + + mPollFds[wake].fd = wakeFds[0]; + mPollFds[wake].events = POLLIN; + mPollFds[wake].revents = 0; + + mAccelActive = false; + mMagnetActive = false; + mOrientationActive = false; +} + +sensors_poll_context_t::~sensors_poll_context_t() { + for (int i=0 ; ienable(handle, enabled); + if (enabled && !err) { + const char wakeMessage(WAKE_MESSAGE); + int result = write(mWritePipeFd, &wakeMessage, 1); + ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno)); + } + return err; +} + +int sensors_poll_context_t::setDelay(int handle, int64_t ns) { + + int index = handleToDriver(handle); + if (index < 0) return index; + return mSensors[index]->setDelay(handle, ns); +} + +int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count) +{ + int nbEvents = 0; + int n = 0; + + do { + // see if we have some leftover from the last poll() + for (int i=0 ; count && ihasPendingEvents())) { + int nb = sensor->readEvents(data, count); + if (nb < count) { + // no more data for this sensor + mPollFds[i].revents = 0; + } + count -= nb; + nbEvents += nb; + data += nb; + } + } + + if (count) { + // we still have some room, so try to see if we can get + // some events immediately or just wait if we don't have + // anything to return + do { + n = poll(mPollFds, numFds, nbEvents ? 0 : -1); + } while (n < 0 && errno == EINTR); + if (n<0) { + ALOGE("poll() failed (%s)", strerror(errno)); + return -errno; + } + if (mPollFds[wake].revents & POLLIN) { + char msg; + int result = read(mPollFds[wake].fd, &msg, 1); + ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno)); + ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg)); + + mPollFds[wake].revents = 0; + } + } + // if we have events and space, go read them + } while (n && count); + + return nbEvents; +} + +/*****************************************************************************/ + +static int poll__close(struct hw_device_t *dev) +{ + sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; + if (ctx) { + delete ctx; + } + return 0; +} + +static int poll__activate(struct sensors_poll_device_t *dev, + int handle, int enabled) { + sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; + return ctx->activate(handle, enabled); +} + +static int poll__setDelay(struct sensors_poll_device_t *dev, + int handle, int64_t ns) { + sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; + return ctx->setDelay(handle, ns); +} + +static int poll__poll(struct sensors_poll_device_t *dev, + sensors_event_t* data, int count) { + sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; + return ctx->pollEvents(data, count); +} + +/*****************************************************************************/ + +/** Open a new instance of a sensor device using name */ +static int open_sensors(const struct hw_module_t* module, const char* id, + struct hw_device_t** device) +{ + int status = -EINVAL; + sensors_poll_context_t *dev = new sensors_poll_context_t(); + + memset(&dev->device, 0, sizeof(sensors_poll_device_t)); + + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast(module); + dev->device.common.close = poll__close; + dev->device.activate = poll__activate; + dev->device.setDelay = poll__setDelay; + dev->device.poll = poll__poll; + + *device = &dev->device.common; + status = 0; + + return status; +} + diff --git a/libsensors/sensors.h b/libsensors/sensors.h new file mode 100644 index 0000000..406754a --- /dev/null +++ b/libsensors/sensors.h @@ -0,0 +1,119 @@ +/* + * 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 ANDROID_SENSORS_H +#define ANDROID_SENSORS_H + +#include +#include +#include +#include + +#include + +#include +#include + +__BEGIN_DECLS + +/*****************************************************************************/ + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +#define ID_A (0) +#define ID_M (1) +#define ID_O (2) +#define ID_L (3) +#define ID_P (4) +#define ID_GY (5) + +/*****************************************************************************/ + +/* + * The SENSORS Module + */ + +/* the GP2A is a binary proximity sensor that triggers around 5 cm on + * this hardware */ +#define PROXIMITY_THRESHOLD_GP2A 5.0f + +/*****************************************************************************/ + +#define EVENT_TYPE_ACCEL_X ABS_X +#define EVENT_TYPE_ACCEL_Y ABS_Y +#define EVENT_TYPE_ACCEL_Z ABS_Z + +#define EVENT_TYPE_YAW REL_X +#define EVENT_TYPE_PITCH REL_Y +#define EVENT_TYPE_ROLL REL_Z +#define EVENT_TYPE_ORIENT_STATUS REL_WHEEL + +/* For AK8973iB */ +#define EVENT_TYPE_MAGV_X ABS_X +#define EVENT_TYPE_MAGV_Y ABS_Y +#define EVENT_TYPE_MAGV_Z ABS_Z + +#define EVENT_TYPE_PROXIMITY ABS_DISTANCE +#define EVENT_TYPE_LIGHT REL_MISC + +#define EVENT_TYPE_GYRO_X REL_RY +#define EVENT_TYPE_GYRO_Y REL_RX +#define EVENT_TYPE_GYRO_Z REL_RZ + +// 720 LSG = 1G +#define NUMOFACCDATA 8 + +// conversion of acceleration data to SI units (m/s^2) +/* Accel BMA250 */ +#define EVENT_TYPE_ACCEL_X ABS_X +#define EVENT_TYPE_ACCEL_Y ABS_Y +#define EVENT_TYPE_ACCEL_Z ABS_Z +#define LSG (1000.0f) + +// conversion of acceleration data to SI units (m/s^2) +#define RANGE_A (4*GRAVITY_EARTH) +#define RESOLUTION_A (GRAVITY_EARTH / LSG) +#define CONVERT_A (GRAVITY_EARTH / LSG) +#define CONVERT_A_X (CONVERT_A) +#define CONVERT_A_Y (CONVERT_A) +#define CONVERT_A_Z (CONVERT_A) + +// conversion of magnetic data to uT units +#define CONVERT_M (1.0f/1000.0.0f) +#define CONVERT_M_X (CONVERT_M) +#define CONVERT_M_Y (CONVERT_M) +#define CONVERT_M_Z (CONVERT_M) + +/* conversion of orientation data to degree units */ +#define CONVERT_O (1.0f/1000.0f) +#define CONVERT_O_A (CONVERT_O) +#define CONVERT_O_P (CONVERT_O) +#define CONVERT_O_R (CONVERT_O) + +// conversion of gyro data to SI units (radian/sec) +#define RANGE_GYRO (2000.0f*(float)M_PI/180.0f) +#define CONVERT_GYRO ((70.0f / 1000.0f) * ((float)M_PI / 180.0f)) +#define CONVERT_GYRO_X (CONVERT_GYRO) +#define CONVERT_GYRO_Y (-CONVERT_GYRO) +#define CONVERT_GYRO_Z (CONVERT_GYRO) + +#define SENSOR_STATE_MASK (0x7FFF) + +/*****************************************************************************/ + +__END_DECLS + +#endif // ANDROID_SENSORS_H diff --git a/n5100.mk b/n5100.mk new file mode 100755 index 0000000..fb0db25 --- /dev/null +++ b/n5100.mk @@ -0,0 +1,87 @@ +# +# Copyright (C) 2012 The CyanogenMod 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 := device/samsung/n5100 + +DEVICE_PACKAGE_OVERLAYS += $(LOCAL_PATH)/overlay + +PRODUCT_AAPT_CONFIG := normal large tvdpi hdpi +PRODUCT_AAPT_PREF_CONFIG := tvdpi + +TARGET_SCREEN_HEIGHT := 1280 +TARGET_SCREEN_WIDTH := 800 + +# Init files +PRODUCT_COPY_FILES += \ + $(LOCAL_PATH)/rootdir/init.smdk4x12.rc:root/init.smdk4x12.rc \ + $(LOCAL_PATH)/rootdir/init.smdk4x12.usb.rc:root/init.smdk4x12.usb.rc \ + $(LOCAL_PATH)/rootdir/ueventd.smdk4x12.rc:root/ueventd.smdk4x12.rc \ + $(LOCAL_PATH)/rootdir/ueventd.smdk4x12.rc:recovery/root/ueventd.smdk4x12.rc \ + $(LOCAL_PATH)/rootdir/lpm.rc:root/lpm.rc \ + $(LOCAL_PATH)/rootdir/fstab.smdk4x12:root/fstab.smdk4x12 + +# Packages +PRODUCT_PACKAGES += \ + tiny_hw \ + libsecril-client \ + libsecril-client-sap \ + DeviceSettings \ + SamsungServiceMode \ + VoicePlus + +PRODUCT_COPY_FILES += \ + $(LOCAL_PATH)/configs/gps.xml:system/etc/gps.xml \ + $(LOCAL_PATH)/configs/nvram_mfg.txt:system/etc/wifi/nvram_mfg.txt \ + $(LOCAL_PATH)/configs/nvram_mfg.txt_murata:system/etc/wifi/nvram_mfg.txt_murata \ + $(LOCAL_PATH)/configs/nvram_net.txt:system/etc/wifi/nvram_net.txt \ + $(LOCAL_PATH)/configs/nvram_net.txt_murata:system/etc/wifi/nvram_net.txt_murata + +# Camera +PRODUCT_PACKAGES += \ + camera.smdk4x12 + +# Sensors +PRODUCT_PACKAGES += \ + sensors.smdk4x12 + +# IRDA +PRODUCT_PACKAGES += \ + irda.exynos4 + +# TWRP +PRODUCT_COPY_FILES += \ + device/samsung/n5100/twrp.fstab:recovery/root/etc/twrp.fstab + +# RIL +PRODUCT_PROPERTY_OVERRIDES += \ + ro.telephony.ril_class=SamsungExynos4RIL \ + mobiledata.interfaces=pdp0,wlan0,gprs,ppp0 \ + ro.ril.hsxpa=1 \ + ro.ril.gprsclass=10 + +# These are the hardware-specific features +PRODUCT_COPY_FILES += \ + frameworks/native/data/etc/android.hardware.telephony.gsm.xml:system/etc/permissions/android.hardware.telephony.gsm.xml \ + frameworks/native/data/etc/android.software.sip.voip.xml:system/etc/permissions/android.software.sip.voip.xml \ + frameworks/native/data/etc/android.software.sip.xml:system/etc/permissions/android.software.sip.xml \ + frameworks/native/data/etc/tablet_core_hardware.xml:system/etc/permissions/handheld_core_hardware.xml + +# Set product characteristic to tablet, needed for some ui elements +PRODUCT_CHARACTERISTICS := tablet + +$(call inherit-product, frameworks/native/build/tablet-7in-xhdpi-2048-dalvik-heap.mk) +$(call inherit-product, vendor/samsung/n5100/n5100-vendor.mk) +$(call inherit-product, device/samsung/smdk4412-common/common.mk) diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml new file mode 100755 index 0000000..d7590f5 --- /dev/null +++ b/overlay/frameworks/base/core/res/res/values/config.xml @@ -0,0 +1,107 @@ + + + + + + + true + + + true + + + true + + true + -1 + 0 + 1 + + + true + + + true + + + pdp0 + + + + + + "wifi,1,1,1,-1,true" + "mobile,0,0,0,-1,true" + "mobile_mms,2,0,2,60000,true" + "mobile_supl,3,0,2,60000,true" + "mobile_dun,4,0,3,60000,true" + "mobile_hipri,5,0,3,60000,true" + "mobile_bluetooth,7,7,1,-1,true" + "wifi_p2p,13,1,0,-1,true" + + + + + 1,1 + 0,1 + 7,1 + + + + + "rndis0" + + + + + "wlan0" + + + + + "bnep\\d" + + + + + + 0 + 1 + 5 + 7 + + + + true + + + true + diff --git a/overlay/frameworks/base/core/res/res/values/config.xml~ b/overlay/frameworks/base/core/res/res/values/config.xml~ new file mode 100755 index 0000000..f6f9a0e --- /dev/null +++ b/overlay/frameworks/base/core/res/res/values/config.xml~ @@ -0,0 +1,104 @@ + + + + + + + true + + + true + + + true + + true + -1 + 0 + 1 + + + true + + + true + + + pdp0 + + + + + + "wifi,1,1,1,-1,true" + "mobile,0,0,0,-1,true" + "mobile_mms,2,0,2,60000,true" + "mobile_supl,3,0,2,60000,true" + "mobile_dun,4,0,3,60000,true" + "mobile_hipri,5,0,3,60000,true" + "mobile_bluetooth,7,7,1,-1,true" + "wifi_p2p,13,1,0,-1,true" + + + + + 1,1 + 0,1 + 7,1 + + + + + "rndis0" + + + + + "wlan0" + + + + + "bnep\\d" + + + + + + 0 + 1 + 5 + 7 + + + + true + diff --git a/overlay/frameworks/base/core/res/res/xml/power_profile.xml b/overlay/frameworks/base/core/res/res/xml/power_profile.xml new file mode 100644 index 0000000..ad5f292 --- /dev/null +++ b/overlay/frameworks/base/core/res/res/xml/power_profile.xml @@ -0,0 +1,61 @@ + + + + + 0 + 302 + 445.8 + 107.6 + 0.6 + 0.4 + 31.0 + 6.5 + 33.5 + 624.5 + 0.2 + 140.9 + 18.5 + + 4.3 + 4.3 + + + 216000 + 312000 + 456000 + 608000 + 760000 + 816000 + 912000 + 1000000 + + 2.2 + 54.6 + + 100 + 107 + 116 + 123 + 135 + 138 + 142 + 148 + + 4600 + diff --git a/overlay/frameworks/base/core/res/res/xml/storage_list.xml b/overlay/frameworks/base/core/res/res/xml/storage_list.xml new file mode 100644 index 0000000..30c5bd6 --- /dev/null +++ b/overlay/frameworks/base/core/res/res/xml/storage_list.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + diff --git a/overlay/packages/apps/Browser/res/values/bools.xml b/overlay/packages/apps/Browser/res/values/bools.xml new file mode 100644 index 0000000..3218656 --- /dev/null +++ b/overlay/packages/apps/Browser/res/values/bools.xml @@ -0,0 +1,16 @@ + + + + true + diff --git a/overlay/packages/apps/Camera/res/values/config.xml b/overlay/packages/apps/Camera/res/values/config.xml new file mode 100644 index 0000000..122b4d2 --- /dev/null +++ b/overlay/packages/apps/Camera/res/values/config.xml @@ -0,0 +1,23 @@ + + + + + + false + diff --git a/overlay/packages/apps/Launcher2/res/values/config.xml b/overlay/packages/apps/Launcher2/res/values/config.xml new file mode 100644 index 0000000..22a4ed5 --- /dev/null +++ b/overlay/packages/apps/Launcher2/res/values/config.xml @@ -0,0 +1,18 @@ + + + + true + diff --git a/overlay/packages/apps/Settings/res/values/arrays.xml b/overlay/packages/apps/Settings/res/values/arrays.xml new file mode 100644 index 0000000..3b47031 --- /dev/null +++ b/overlay/packages/apps/Settings/res/values/arrays.xml @@ -0,0 +1,46 @@ + + + + + + 15 seconds + 30 seconds + 1 minute + 2 minutes + 5 minutes + 10 minutes + + + + + + 15000 + + 30000 + + 60000 + + 120000 + + 300000 + + 600000 + + diff --git a/overlay/packages/apps/Settings/res/values/bools.xml b/overlay/packages/apps/Settings/res/values/bools.xml new file mode 100644 index 0000000..2ebd9dd --- /dev/null +++ b/overlay/packages/apps/Settings/res/values/bools.xml @@ -0,0 +1,23 @@ + + + + + + true + + + true + diff --git a/overlay/packages/apps/Settings/res/values/config.xml b/overlay/packages/apps/Settings/res/values/config.xml new file mode 100644 index 0000000..a4a7315 --- /dev/null +++ b/overlay/packages/apps/Settings/res/values/config.xml @@ -0,0 +1,20 @@ + + + + + true + diff --git a/overlay/packages/apps/SystemUI/res/values/config.xml b/overlay/packages/apps/SystemUI/res/values/config.xml new file mode 100755 index 0000000..88851f7 --- /dev/null +++ b/overlay/packages/apps/SystemUI/res/values/config.xml @@ -0,0 +1,26 @@ + + + + + + + true + + diff --git a/overlay/packages/apps/Torch/res/values/config.xml b/overlay/packages/apps/Torch/res/values/config.xml new file mode 100644 index 0000000..d13de94 --- /dev/null +++ b/overlay/packages/apps/Torch/res/values/config.xml @@ -0,0 +1,36 @@ + + + + + + + false + + + /sys/class/camera/rear/rear_flash + + + 1 + + -1 + + -1 + + diff --git a/proprietary-files.txt b/proprietary-files.txt new file mode 100644 index 0000000..25c0d21 --- /dev/null +++ b/proprietary-files.txt @@ -0,0 +1,3 @@ +system/lib/libril-qc-qmi-1.so +system/lib/libril-qcril-hook-oem.so +system/lib/libril.so diff --git a/rootdir/fstab.smdk4x12 b/rootdir/fstab.smdk4x12 new file mode 100644 index 0000000..5068276 --- /dev/null +++ b/rootdir/fstab.smdk4x12 @@ -0,0 +1,19 @@ +# Android fstab file. +# +# The filesystem that contains the filesystem checker binary (typically /system) cannot +# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK +# data partition must be located at the bottom for supporting device encryption +/dev/block/mmcblk0p9 /system ext4 ro,errors=panic wait +/dev/block/mmcblk0p3 /efs ext4 nosuid,nodev,noatime,noauto_da_alloc,discard,journal_async_commit,errors=panic wait,check +/dev/block/mmcblk0p8 /cache ext4 nosuid,nodev,noatime,noauto_da_alloc,discard,journal_async_commit,errors=panic wait,check +/dev/block/mmcblk0p12 /data ext4 nosuid,nodev,noatime,noauto_da_alloc,discard,journal_async_commit,errors=panic wait,check,encryptable=footer + +# vold-managed volumes ("block device" is actually a sysfs devpath) +/devices/platform/s3c-sdhci.2/mmc_host/mmc1 /storage/sdcard1 auto defaults voldmanaged=sdcard1:auto +/devices/platform/s5p-ehci /storage/usbdisk0 auto defaults voldmanaged=usbdisk0:auto + +# recovery +/dev/block/mmcblk0p5 /boot emmc defaults recoveryonly +/dev/block/mmcblk0p6 /recovery emmc defaults recoveryonly +/dev/block/mmcblk0p7 /modem emmc defaults recoveryonly +/dev/block/mmcblk1p1 /external_sd auto defaults recoveryonly diff --git a/rootdir/init.smdk4x12.rc b/rootdir/init.smdk4x12.rc new file mode 100755 index 0000000..d0b9305 --- /dev/null +++ b/rootdir/init.smdk4x12.rc @@ -0,0 +1,592 @@ +import init.smdk4x12.usb.rc + +on init + mkdir /mnt/shell/emulated 0700 shell shell + mkdir /storage 0550 system sdcard_r + mkdir /storage/emulated 0555 root root + mkdir /storage/sdcard1 0775 system system + mkdir /storage/usbdisk0 0775 system system + + export EXTERNAL_STORAGE /storage/emulated/legacy + export SECONDARY_STORAGE /storage/sdcard1 + export EMULATED_STORAGE_SOURCE /mnt/shell/emulated + export EMULATED_STORAGE_TARGET /storage/emulated + + # for backwards compatibility + symlink /storage/emulated/legacy /sdcard + symlink /storage/emulated/legacy /mnt/sdcard + symlink /storage/emulated/legacy /storage/sdcard0 + symlink /mnt/shell/emulated/0 /storage/emulated/legacy + symlink /storage/sdcard1 /extSdCard + symlink /storage/sdcard1 /mnt/extSdCard + symlink /storage/usbdisk0 /usbdisk0 + symlink /storage/usbdisk0 /mnt/usbdisk0 + + mkdir /efs 0771 radio system + mkdir /tombstones + symlink /efs /factory + + +# ko files for FM Radio + #insmod /system/lib/modules/Si4709_driver.ko + +on init + + # Vibetonz + export VIBE_PIPE_PATH /dev/pipes + mkdir /dev/pipes 0771 shell shell + +on fs + mount_all /fstab.smdk4x12 + + setprop ro.crypto.fuse_sdcard true + + chown radio system /efs + chmod 0771 /efs + +on post-fs-data + # we will remap this as /mnt/sdcard with the sdcard fuse tool + mkdir /data/media 0775 media_rw media_rw + chown media_rw media_rw /data/media + +# for AT distributor + chown system radio /sys/module/cpuidle_exynos4/parameters/enable_mask + chmod 0664 /sys/module/cpuidle_exynos4/parameters/enable_mask + +# data/log + mkdir /data/log 0775 system log + chown system log /data/log + chmod 0775 /data/log + chmod 0775 /data/anr + + # create data/gps for GPS demon + chown root system /dev/ttySAC1 + chmod 0660 /dev/ttySAC1 + chown root system /sys/class/sec/gps/GPS_PWR_EN/value + chmod 0664 /sys/class/sec/gps/GPS_PWR_EN/value + chown root system /sys/class/sec/gps/GPS_nRST/value + chmod 0664 /sys/class/sec/gps/GPS_nRST/value + mkdir /data/gps 771 system system + chown system system /data/gps + + mkdir /data/misc/radio 0775 radio system + chmod 0775 /data/misc/radio + mkdir /efs/imei 0775 radio system + + mkdir /data/local/audio 0775 media audio + chown media audio /data/local/audio + +# HDCP 2.x + mkdir /data/system/hdcp2 0775 system system + +# h2k permission + chmod 0644 /efs/redata.bin + chmod 0644 /efs/h2k.dat + +# Camera firmware + mkdir /data/cfw 0775 system system + chown system media /data/cfw/SlimISP_GK.bin + chmod 0775 /data/cfw/SlimISP_GK.bin + chown system media /data/cfw/SlimISP_ZK.bin + chmod 0775 /data/cfw/SlimISP_ZK.bin + +# Camera + chown system radio /sys/class/camera/rear/rear_camfw + chown system radio /sys/class/camera/rear/rear_camtype + chown system radio /sys/class/camera/rear/rear_flash + chmod 0666 /sys/class/camera/flash/rear_flash + chown system radio /sys/class/camera/rear/isp_core + chown system radio /sys/class/camera/front/front_camfw + chown system radio /sys/class/camera/front/front_camtype + chown system radio /sys/class/camera/flash/rear_flash + chown radio system /sys/devices/platform/samsung-pd.5/s3c-fimc.2/range_mode + chmod 0660 /sys/devices/platform/samsung-pd.5/s3c-fimc.2/range_mode + + symlink /dev/block/mmcblk0p4 /dev/block/param + +# Permissions for bluetooth + setprop ro.bt.bdaddr_path "/efs/bluetooth/bt_addr" + chown bluetooth bluetooth ro.bt.bdaddr_path + chown bluetooth bluetooth /dev/ttySAC0 + chmod 0600 /dev/ttySAC0 + chmod 0660 /sys/class/rfkill/rfkill0/state + chown bluetooth bluetooth /sys/class/rfkill/rfkill0/state + chown bluetooth bluetooth /sys/class/rfkill/rfkill0/type + +# Vibrator + chmod 0660 /dev/tspdrv + chown root shell /dev/tspdrv + chmod 0660 /sys/class/timed_output/vibrator/pwm_value + chown system system /sys/class/timed_output/vibrator/pwm_value + +# serial keyboard port + chown root system /dev/ttySAC3 + chmod 0660 /dev/ttySAC3 + +# for datarouter + chown system system /dev/dun + chown system system /dev/ttyGS0 + chown system system /dev/ttyGS1 + chown system system /dev/ttyGS2 + chown system system /dev/ttyGS3 + +# NFC + setprop ro.nfc.port "I2C" + chmod 0600 /dev/pn544 + chown nfc nfc /dev/pn544 + +# Permissions for LCD + chown system radio /sys/class/lcd/panel/lcd_type + chown system system /sys/class/backlight/panel/auto_brightness + +# Permissions for mDNIe + chown system media_rw /sys/class/mdnie/mdnie/mode + chown system media_rw /sys/class/mdnie/mdnie/outdoor + chown system media_rw /sys/class/mdnie/mdnie/scenario + chown system system /sys/class/mdnie/mdnie/negative + chown system system /sys/class/mdnie/mdnie/ebook + chown system system /sys/class/mdnie/mdnie/accessibility + chown system system /sys/class/mdnie/mdnie/cabc + write /sys/class/mdnie/mdnie/scenario 0 + write /sys/class/mdnie/mdnie/mode 0 + +# Permissions for Touchkey + chown system radio /sys/class/sec/sec_touchkey/touchkey_dummy_btn1 + chown system radio /sys/class/sec/sec_touchkey/touchkey_dummy_btn3 + chown system radio /sys/class/sec/sec_touchkey/touchkey_dummy_btn5 + chown system radio /sys/class/sec/sec_touchkey/touchkey_menu + chown system radio /sys/class/sec/sec_touchkey/extra_button_event + chown system radio /sys/class/sec/sec_touchkey/touchkey_button_all + chown system radio /sys/class/sec/sec_touchkey/touchkey_button_status + chown system radio /sys/class/sec/sec_touchkey/touchkey_threshold + chown system radio /sys/class/sec/sec_touchkey/brightness + chmod 0660 /sys/class/sec/sec_touchkey/extra_button_event + chown system system /sys/devices/virtual/sec/sec_touchkey/brightness + +# Permissions for Hall IC + chown system radio /sys/class/sec/sec_key/hall_detect + +# Permissions for System Server and daemons. + chown radio system /sys/android_power/state + chown radio system /sys/android_power/request_state + chown radio system /sys/android_power/acquire_full_wake_lock + chown radio system /sys/android_power/acquire_partial_wake_lock + chown radio system /sys/android_power/release_wake_lock + chown radio system /sys/power/state + chown radio system /sys/power/wake_lock + chown radio system /sys/power/wake_unlock + chown radio system /sys/power/cpufreq_table + chown radio system /sys/power/cpufreq_max_limit + chown radio system /sys/power/cpufreq_min_limit + chown radio system /sys/power/mali_lock + chown radio system /sys/class/power_supply/battery/siop_activated + chown radio system /sys/devices/system/cpu/cpufreq/pegasusq/max_cpu_lock + chown radio system /sys/devices/system/cpu/cpufreq/pegasusq/hotplug_lock + chown radio system /sys/devices/system/cpu/busfreq/curr_freq + chown radio system /sys/module/mali/parameters/mali_dvfs_control + chown system radio /sys/bus/platform/devices/s5p-tmu/lot_id + chmod 0660 /sys/power/state + chmod 0660 /sys/power/wake_lock + chmod 0660 /sys/power/wake_unlock + chmod 0660 /sys/power/cpufreq_table + chmod 0660 /sys/power/cpufreq_max_limit + chmod 0660 /sys/power/cpufreq_min_limit + chmod 0660 /sys/power/mali_lock + chmod 0660 /sys/class/power_supply/battery/siop_activated + chmod 0660 /sys/devices/system/cpu/cpufreq/pegasusq/max_cpu_lock + chmod 0660 /sys/devices/system/cpu/cpufreq/pegasusq/hotplug_lock + chmod 0660 /sys/devices/system/cpu/busfreq/curr_freq + chmod 0660 /sys/module/mali/parameters/mali_dvfs_control + chmod 0664 /sys/bus/platform/devices/s5p-tmu/lot_id + chown system system /sys/class/timed_output/vibrator/enable + chown system system /sys/class/leds/keyboard-backlight/brightness + chown system system /sys/class/leds/lcd-backlight/brightness + chown system system /sys/class/backlight/panel/brightness + chown system system /sys/class/leds/button-backlight/brightness + chown system system /sys/class/sec/sec_touchkey/brightness + chown system system /sys/class/leds/jogball-backlight/brightness + chown system system /sys/class/leds/red/brightness + chown system system /sys/class/leds/green/brightness + chown system system /sys/class/leds/blue/brightness + chown system system /sys/class/leds/red/device/grpfreq + chown system system /sys/class/leds/red/device/grppwm + chown system system /sys/class/leds/red/device/blink + chown system system /sys/class/leds/red/brightness + chown system system /sys/class/leds/green/brightness + chown system system /sys/class/leds/blue/brightness + chown system system /sys/class/leds/red/device/grpfreq + chown system system /sys/class/leds/red/device/grppwm + chown system system /sys/class/leds/red/device/blink + chown system system /sys/class/timed_output/vibrator/enable + chown system system /sys/module/sco/parameters/disable_esco + chown system system /sys/kernel/ipv4/tcp_wmem_min + chown system system /sys/kernel/ipv4/tcp_wmem_def + chown system system /sys/kernel/ipv4/tcp_wmem_max + chown system system /sys/kernel/ipv4/tcp_rmem_min + chown system system /sys/kernel/ipv4/tcp_rmem_def + chown system system /sys/kernel/ipv4/tcp_rmem_max + chown root radio /proc/cmdline + +# Audio (Earjack) + chown system radio /sys/class/audio/earjack/select_jack + chown system radio /sys/class/audio/earjack/key_state + chown system radio /sys/class/audio/earjack/state + chown media system /sys/class/audio/earjack/reselect_jack + +# Battery node + chown system radio /sys/class/power_supply/battery/batt_charging_source + chown system radio /sys/class/power_supply/battery/batt_error_test + chown system radio /sys/class/power_supply/battery/batt_lp_charging + chown system radio /sys/class/power_supply/battery/batt_read_adj_soc + chown system radio /sys/class/power_supply/battery/batt_read_raw_soc + chown system radio /sys/class/power_supply/battery/batt_reset_soc + chown system radio /sys/class/power_supply/battery/batt_slate_mode + chown system radio /sys/class/power_supply/battery/batt_temp_adc + chown system radio /sys/class/power_supply/battery/batt_temp_adc_aver + chown system radio /sys/class/power_supply/battery/batt_temp_adc_cal + chown system radio /sys/class/power_supply/battery/batt_temp_aver + chown system radio /sys/class/power_supply/battery/batt_type + chown system radio /sys/class/power_supply/battery/batt_vf_adc + chown system radio /sys/class/power_supply/battery/batt_vfocv + chown system radio /sys/class/power_supply/battery/batt_vol_adc + chown system radio /sys/class/power_supply/battery/batt_vol_adc_aver + chown system radio /sys/class/power_supply/battery/batt_vol_adc_cal + chown system radio /sys/class/power_supply/battery/batt_vol_aver + chown system radio /sys/class/power_supply/battery/factory_mode + chown system radio /sys/class/power_supply/battery/siop_activated + chown system radio /sys/class/power_supply/battery/siop_level + chown system radio /sys/class/power_supply/battery/update + chown system radio /sys/class/power_supply/battery/wc_status + chown system radio /sys/class/power_supply/battery/wpc_pin_state + +# CTIA event + chown sdcard_rw sdcard_rw /sys/class/power_supply/battery/call + chown sdcard_rw sdcard_rw /sys/class/power_supply/battery/video + chown sdcard_rw sdcard_rw /sys/class/power_supply/battery/music + chown sdcard_rw sdcard_rw /sys/class/power_supply/battery/browser + chown sdcard_rw sdcard_rw /sys/class/power_supply/battery/hotspot + chown sdcard_rw sdcard_rw /sys/class/power_supply/battery/camera + chown system radio /sys/class/power_supply/battery/talk_wcdma + chown system radio /sys/class/power_supply/battery/talk_gsm + chown system radio /sys/class/power_supply/battery/call + chown system radio /sys/class/power_supply/battery/data_call + chown gps radio /sys/class/power_supply/battery/gps + chown system radio /sys/class/power_supply/battery/wifi + chown system radio /sys/class/power_supply/battery/lte + +# Thermistor node + chown radio system /sys/devices/platform/sec-thermistor/temp_adc + chown radio system /sys/devices/platform/sec-thermistor/temperature + +# Permissions for touch + chown system radio /sys/class/sec/tsp/cmd + +# Permissions for Touchkey + chown system radio /sys/class/sec/sec_touchkey/enable_disable + chown system radio /sys/class/sec/sec_touchkey/touchkey_menu + chown system radio /sys/class/sec/sec_touchkey/touchkey_back + chown system radio /sys/class/sec/sec_touchkey/touch_update + chown system radio /sys/class/sec/sec_touchkey/touch_version + chown system radio /sys/class/sec/sec_touchkey/touchkey_firm_version_panel + chown system radio /sys/class/sec/sec_touchkey/touchkey_firm_version_phone + chown system radio /sys/class/sec/sec_touchkey/touchkey_firm_update_status + chown system radio /sys/class/sec/sec_touchkey/touchkey_firm_update + chown system radio /sys/class/sec/sec_touchkey/touch_sensitivity + chown system radio /sys/class/sec/sec_touchkey/touchkey_threshold + chown system system /sys/devices/virtual/sec/sec_touchkey/brightness + +# Permissions for gpio_keys + chown radio system /sys/class/sec/sec_key/wakeup_keys + write /sys/class/sec/sec_key/wakeup_keys 116,172,544 + +# Switch Device + chown system system /sys/class/sec/switch/uart_sel + chown system system /sys/class/sec/switch/usb_sel + chown system system /sys/class/sec/switch/otg_test + chown system radio /sys/class/sec/switch/adc + +# IPC sysfs + chown radio radio /sys/devices/virtual/misc/multipdp/waketime + symlink /dev/block/mmcblk0p7 /dev/mbin0 + +# +# Input Events + chown system input /sys/class/input/input2/enable + chown system input /sys/class/input/input2/poll_delay + chown system input /sys/class/input/input3/enable + chown system input /sys/class/input/input3/poll_delay + chown system input /sys/class/input/input4/enable + chown system input /sys/class/input/input4/poll_delay + chown system input /sys/class/input/input5/enable + chown system input /sys/class/input/input5/poll_delay + chown system input /sys/class/input/input6/enable + chown system input /sys/class/input/input6/poll_delay + chown system input /sys/class/input/input7/enable + chown system input /sys/class/input/input7/poll_delay + chown system input /sys/class/input/input8/enable + chown system input /sys/class/input/input8/poll_delay + chown system input /sys/class/input/input9/enable + chown system input /sys/class/input/input9/poll_delay + chown system input /sys/class/input/input2/delay + chown system input /sys/class/input/input3/delay + chown system input /sys/class/input/input4/delay + chown system input /sys/class/input/input5/delay + chown system input /sys/class/input/input6/delay + chown system input /sys/class/input/input6/delay + chown system input /sys/class/input/input7/delay + chown system input /sys/class/input/input8/delay + chown system input /sys/class/input/input9/delay +# Accelerometer_sensor + chown system radio /dev/accelerometer + chown system radio /sys/class/sensors/accelerometer_sensor + chown system radio /sys/class/sensors/accelerometer_sensor/raw_data + chown system radio /sys/class/sensors/accelerometer_sensor/calibration + chown system radio /sys/class/sensors/accelerometer_sensor/reactive_alert + chown system radio /sys/class/sensors/accelerometer_sensor/vendor + chown system radio /sys/class/sensors/accelerometer_sensor/name +# Proximity_sensor + chown system radio /sys/class/sensors/proximity_sensor/state + chown system radio /sys/class/sensors/proximity_sensor/prox_avg + chown system radio /sys/class/sensors/proximity_sensor/prox_cal + chown system radio /sys/class/sensors/proximity_sensor/vendor + chown system radio /sys/class/sensors/proximity_sensor/name + chown system radio /sys/class/sensors/proximity_sensor/prox_thresh +# Light_sensor + chown system radio /sys/class/sensors/light_sensor/lux + chown system radio /sys/class/sensors/light_sensor/raw_data + chown system radio /sys/class/sensors/light_sensor/vendor + chown system radio /sys/class/sensors/light_sensor/name +# Magnetic_sensor + chmod 0777 /dev/i2c-10 + chown system radio /sys/class/sensors/magnetic_sensor/raw_data + chown system radio /sys/class/sensors/magnetic_sensor/vendor + chown system radio /sys/class/sensors/magnetic_sensor/name + chown compass input /sys/class/input/input6/offsets + chown compass input /sys/class/input/input6/dynamic_matrix + chown system input /sys/class/input/input6/threshold + chown system input /sys/class/input/input6/distortion + chown system input /sys/class/input/input6/shape + write /sys/class/input/input6/distortion "350 50 15" + write /sys/class/input/input6/static_matrix "10602 -980 25 -830 10470 -188 2753 1005 9019" + write /sys/class/input/input6/ellipsoid_mode "1" + + chown system input /sys/class/input/input6/filter_enable + chown system input /sys/class/input/input6/filter_len + chown system input /sys/class/input/input6/data + chown system input /sys/class/input/input6/status + chown system input /sys/class/input/input6/wake + chown system input /sys/class/input/input6/position +# Magnetic_sensor + chown compass input /sys/class/input/input5/offsets + chown compass input /sys/class/input/input5/dynamic_matrix + chown system input /sys/class/input/input5/threshold + chown system input /sys/class/input/input5/distortion + chown system input /sys/class/input/input5/shape + write /sys/class/input/input5/distortion "350 50 15" + write /sys/class/input/input5/static_matrix "10602 -980 25 -830 10470 -188 2753 1005 9019" + write /sys/class/input/input5/ellipsoid_mode "1" + + chown system input /sys/class/input/input5/filter_enable + chown system input /sys/class/input/input5/filter_len + chown system input /sys/class/input/input5/data + chown system input /sys/class/input/input5/status + chown system input /sys/class/input/input5/wake + chown system input /sys/class/input/input5/position + +# NFC + setprop ro.nfc.port "I2C" + chmod 0600 /dev/pn544 + chown nfc nfc /dev/pn544 + +# Vibetonz + chmod 0660 /dev/tspdrv + chown root shell /dev/tspdrv + +# IR_LED + chown system system /sys/class/sec/sec_ir/ir_send + chown system system /sys/class/sec/sec_ir/ir_send_result + +# Permissions for backlight + chown system system /sys/class/backlight/panel/brightness + +# for wifi + mkdir /data/misc/wifi/sockets 0770 wifi wifi + mkdir /data/misc/dhcp 0775 dhcp dhcp + chown dhcp dhcp /data/misc/dhcp + +# for TRP/TIS + write /data/.psm.info 1 + chown system root /data/.psm.info + chmod 0660 /data/.psm.info + + # Set indication (checked by vold) that we have finished this action + setprop vold.post_fs_data_done 1 + +on boot + mount debugfs /sys/kernel/debug /sys/kernel/debug + + setprop ro.build.product smdk4x12 + setprop ro.product.device smdk4x12 + setprop wifi.interface wlan0 + +# fake some battery state + setprop status.battery.state Slow + setprop status.battery.level 5 + setprop status.battery.level_raw 50 + setprop status.battery.level_scale 9 + +# wifi display + write /proc/sys/net/core/wmem_max 262144 + + # Set permission for Widevine DRM temporarily + chmod 0777 /dev/s5p-smem + rm /data/app/tlcd_sock + + # make param block device link for SysScope + symlink /dev/block/mmcblk0p7 /dev/block/param + +# touchscreen + chown radio system /sys/class/sec/tsp/cmd + chown media_rw media_rw /sys/class/sec/tsp/set_jitter + +# epen + chown radio system /sys/class/sec/sec_epen/epen_firm_update + chown radio system /sys/class/sec/sec_epen/epen_checksum + chown radio system /sys/class/sec/sec_epen/epen_checksum_result + chown radio system /sys/class/sec/sec_epen/epen_reset + chown system system /sys/class/sec/sec_epen/epen_saving_mode + chmod 660 /sys/class/sec/sec_epen/epen_saving_mode + +# wakeup keys + chown radio system /sys/class/sec/sec_key/wakeup_keys + write /sys/class/sec/sec_key/wakeup_keys 116,172 + +# serial keyboard daemon +service sec_keyboard /system/bin/sec_keyboard /dev/ttySAC3 + class late_start + disabled + group system + +# SISO-ANDR_PERF :: START Changing scheduler to cfq and reseting cpu min freq to -1 after boot complete +on property:sys.boot_completed=1 + write /sys/block/mmcblk0/queue/scheduler cfq + write /sys/power/cpufreq_min_limit -1 +# SISO-ANDR_PERF :: END + +on property:ro.uart_debug=0 + start sec_keyboard + +# create filesystem if necessary +#service setup_fs /system/bin/setup_fs \ +# /dev/block/mmcblk0p3 \ +# /dev/block/mmcblk0p4 +# class core +# user root +# group root +# oneshot + +service at_distributor /system/bin/at_distributor + class main + user root + group radio log + +# create virtual SD card at /mnt/sdcard, based on the /data/media directory +# daemon will drop to user/group system/media_rw after initializing +# underlying files in /data/media wil be created with user and group media_rw (1023) +service sdcard /system/bin/sdcard /data/media /mnt/shell/emulated 1023 1023 + class late_start + +service p2p_supplicant /system/bin/wpa_supplicant \ + -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf -N \ + -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf -e/data/misc/wifi/entropy.bin \ + -puse_p2p_group_interface=1 + # we will start as root and wpa_supplicant will switch to user wifi + # after setting up the capabilities required for WEXT + # user wifi + # group wifi inet keystore + class main + socket wpa_wlan0 dgram 660 wifi wifi + disabled + oneshot + +service wpa_supplicant /system/bin/wpa_supplicant \ + -Dnl80211 -iwlan0 -e/data/misc/wifi/entropy.bin \ + -c/data/misc/wifi/wpa_supplicant.conf + # we will start as root and wpa_supplicant will switch to user wifi + # after setting up the capabilities required for WEXT + # user wifi + # group wifi inet keystore + class main + socket wpa_wlan0 dgram 660 wifi wifi + disabled + oneshot + +service dhcpcd_wlan0 /system/bin/dhcpcd -ABKL + class main + disabled + oneshot + +service dhcpcd_p2p /system/bin/dhcpcd -aABKL + class main + disabled + oneshot + +service dhcpcd_bnep0 /system/bin/dhcpcd -ABKL + class main + disabled + oneshot + +service iprenew_wlan0 /system/bin/dhcpcd -n + class main + disabled + oneshot + +service iprenew_p2p /system/bin/dhcpcd -n + class main + disabled + oneshot + +service iprenew_bnep0 /system/bin/dhcpcd -n + class main + disabled + oneshot + +# GPS +service gpsd /system/bin/gpsd -c /system/etc/gps.xml + class main + socket gps seqpacket 0660 gps system + user gps + group system inet sdcard_rw + ioprio be 0 + +service macloader /system/bin/macloader + class main + oneshot + +# cbd +service cpboot-daemon /sbin/cbd -d + class main + user root + group radio cache inet misc audio sdcard_rw log sdcard_r + +service orientationd /system/bin/orientationd + class main + user compass + group input + +service geomagneticd /system/bin/geomagneticd + class main + user compass + group system input + +on property:init.svc.macloader=stopped + chown system root /data/.cid.info + chmod 0664 /data/.cid.info + chown system root /data/.rev + chmod 0660 /data/.rev +# end of wifi + +service SMD-daemon /system/bin/smdexe + class main + user root + group system radio inet net_raw diff --git a/rootdir/init.smdk4x12.usb.rc b/rootdir/init.smdk4x12.usb.rc new file mode 100755 index 0000000..6c4bca2 --- /dev/null +++ b/rootdir/init.smdk4x12.usb.rc @@ -0,0 +1,134 @@ +on init + write /sys/class/android_usb/android0/iSerial $ro.serialno + write /sys/class/android_usb/android0/f_rndis/manufacturer Samsung + write /sys/class/android_usb/android0/f_rndis/vendorID 04e8 + write /sys/class/android_usb/android0/f_rndis/wceis 1 + +on boot + write /sys/class/android_usb/android0/iManufacturer $ro.product.manufacturer + write /sys/class/android_usb/android0/iProduct $ro.product.model + write /sys/class/android_usb/android0/iSerial $ro.serialno + write /sys/class/android_usb/f_mass_storage/inquiry_string "Samsung" + +on property:sys.usb.config=mtp + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 6860 + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + setprop sys.usb.state ${sys.usb.config} + + +on property:sys.usb.config=mtp,adb + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 6860 + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + start adbd + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=rndis + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 6863 + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/bDeviceClass 224 + write /sys/class/android_usb/android0/enable 1 + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=rndis,adb + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 6864 + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/bDeviceClass 224 + write /sys/class/android_usb/android0/enable 1 + start adbd + setprop sys.usb.state ${sys.usb.config} +on property:sys.usb.config=ptp + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 6865 + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=ptp,adb + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 6866 + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + start adbd + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=rndis,dm + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 6862 + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=rndis,acm,dm + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 6862 + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=mass_storage + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 685B + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=mass_storage,adb + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 685e + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + start adbd + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=mass_storage,acm + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 685e + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + setprop sys.usb.state ${sys.usb.config} +# rndis,acm,diag and diag,acm,adb used for Hidden Menu + +on property:sys.usb.config=rndis,diag + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 6862 + write /sys/class/android_usb/android0/f_diag/clients diag_mdm + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=diag,acm,adb + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04E8 + write /sys/class/android_usb/android0/idProduct 6860 + write /sys/class/android_usb/android0/f_diag/clients diag_mdm + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + start adbd + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=rndis,acm,diag + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04E8 + write /sys/class/android_usb/android0/idProduct 6864 + write /sys/class/android_usb/android0/f_diag/clients diag_mdm + write /sys/class/android_usb/android0/functions ${sys.usb.config} + write /sys/class/android_usb/android0/enable 1 + setprop sys.usb.state ${sys.usb.config} diff --git a/rootdir/lpm.rc b/rootdir/lpm.rc new file mode 100644 index 0000000..a9a183d --- /dev/null +++ b/rootdir/lpm.rc @@ -0,0 +1,82 @@ +on early-init + start ueventd + +on init + + export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin + export LD_LIBRARY_PATH /vendor/lib:/system/lib + export ANDROID_ROOT /system + export ANDROID_DATA /data + export EXTERNAL_STORAGE /sdcard + + symlink /system/etc /etc + + mkdir /sdcard + mkdir /preload + mkdir /system + mkdir /data + mkdir /cache + mkdir /efs + mkdir /tmp + mkdir /dbdata + mkdir /mnt 0775 root root + #mount /tmp /tmp tmpfs + +on early-fs +# insmod /lib/modules/vibrator.ko + + mount ext4 /dev/block/mmcblk0p9 /system ro wait noatime + + mkdir /data/log 0777 + + chmod 0666 /dev/log/radio + chmod 0666 /dev/log/main + chmod 0666 /dev/log/event + +on boot +# write /sys/class/sec/switch/usb_sel PDA + +# CPU Frequency Governor + write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor pegasusq + +# EHCI runtime enable for LPA + write /sys/devices/platform/s5p-ehci/power/control auto + + ifup lo + hostname localhost + domainname localdomain + + class_start default + +service debuggerd /system/bin/debuggerd + +service ueventd /sbin/ueventd + critical + +#service console /bin/sh +service console /system/bin/sh + console + +service playlpm /system/bin/playlpm + user root + +service immvibed /system/bin/immvibed + oneshot + +service lpmkey /system/bin/lpmkey + user root + +# adbd is controlled by the persist.service.adb.enable system property +service adbd /sbin/adbd + disabled + +# adbd on at boot in emulator +on property:ro.kernel.qemu=1 + start adbd + +on property:persist.service.adb.enable=1 + start adbd + +on property:persist.service.adb.enable=0 + stop adbd + diff --git a/rootdir/ueventd.smdk4x12.rc b/rootdir/ueventd.smdk4x12.rc new file mode 100644 index 0000000..f073117 --- /dev/null +++ b/rootdir/ueventd.smdk4x12.rc @@ -0,0 +1,83 @@ +/dev/mali 0666 system system +/dev/ump 0666 system graphics +/dev/ion 0666 system system +/dev/exynos-mem 0666 system graphics + +/dev/media0 0660 system system +/dev/media1 0660 system camera +/dev/media2 0660 system camera +/dev/v4l-subdev0 0660 system system +/dev/v4l-subdev1 0660 system system +/dev/v4l-subdev3 0660 system system +/dev/v4l-subdev4 0660 system system +/dev/v4l-subdev5 0660 system system +/dev/v4l-subdev6 0660 system system +/dev/v4l-subdev7 0660 system system +/dev/v4l-subdev8 0660 system system +/dev/v4l-subdev9 0660 system system +/dev/v4l-subdev10 0660 system system +/dev/v4l-subdev11 0660 system system +/dev/v4l-subdev12 0660 system system +/dev/v4l-subdev13 0660 system system +/dev/v4l-subdev14 0660 system system +/dev/v4l-subdev15 0660 system system +/dev/v4l-subdev16 0660 system system +/dev/v4l-subdev17 0660 system system + +/dev/video0 0660 system camera +/dev/video1 0660 system camera +/dev/video2 0660 system camera +/dev/video3 0660 system camera +/dev/video4 0666 system graphics +/dev/video11 0666 system system +/dev/video12 0666 system system +/dev/video20 0660 system system +/dev/video6 0660 media graphics +/dev/video7 0660 media graphics + +/dev/video11 0666 system graphics +/dev/video12 0660 system camera + +/dev/video16 0660 system system +/dev/video17 0660 system system +/dev/video18 0660 system system +/dev/video19 0660 system system + +# Rotator +/dev/video21 0660 system system + +/dev/video23 0660 system system +/dev/video24 0660 system system +/dev/video25 0660 system camera +/dev/video26 0666 media graphics +/dev/video29 0666 media graphics +/dev/video32 0660 media graphics + +/dev/video33 0660 system system +/dev/video34 0660 system system + +/dev/video40 0660 system camera +/dev/video41 0660 system camera +/dev/video42 0660 system camera +/dev/video43 0660 system camera + +/dev/i2c-2 0660 system system +/dev/i2c-5 0660 system system +/dev/CEC 0660 system system +/dev/HPD 0660 system system +/dev/fimg2d 0666 system graphics +/dev/fmradio 0660 system audio + +#ALP Audio +/dev/srp 0660 system audio + +/dev/s3c-mfc 0666 system graphics +/dev/s5p-mfc 0666 system graphics + +/dev/umts* 0660 system radio +/dev/ttyUSB0 0666 system system +/dev/ttyUSB1 0666 system system +/dev/ttyUSB2 0666 system system +/dev/usb/lp* 0660 system usb +/dev/block/mmcblk0p4 0660 system system +/dev/block/mmcblk0p7 0660 system radio diff --git a/secril_multi/Oem_ril_sap.h b/secril_multi/Oem_ril_sap.h new file mode 100755 index 0000000..6f90e6a --- /dev/null +++ b/secril_multi/Oem_ril_sap.h @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2009 Samsung Electronics, Co. Ltd. + * All rights reserved. + * + * Oem_ril_sap.h + * + * author: young jin Park (lucky29.park@samsung.com) + * data : 20100129 +*/ + +#ifndef __OEM_RIL_SAP_H__ +#define __OEM_RIL_SAP_H__ + +/** + * OEM request header data(for RIL_REQUEST_OEM_HOOK_RAW) + +typedef struct _OemReqDataHdr +{ + char func_id; + char sub_func_id; + char len; +} __attribute__((packed)) OemReqDataHdr; + + + * OEM request data(for RIL_REQUEST_OEM_HOOK_RAW) + +typedef struct _OemReqData +{ + OemReqDataHdr hdr; + char *payload; +} __attribute__((packed)) OemReqData; + +**/ + +/* -- OEM RIL SAP Main Cmd --*/ +#define OEM_FUNCTION_ID_SAP 0x14 + +/* -- OEM RIL SAP SUB FUNCTION ID -- */ + +#define OEM_SAP_CONNECT 0x01 +/** OEM_SAP_CONNECT + Req - Format info + 1. MSG ID (1 byte) + + Res - Format info + 1. MSG ID (1 byte) + 2. CONNECTION STATUS (1 byte) + 3. MAX MSG SIZE (2 byte) + + Noti(Unsol) - Format info + 1. DISCONNECT TYPE (1 byte) +**/ + +#define OEM_SAP_STATUS 0x02 +/** OEM_SAP_STATUS + Req - Format info + non. + + Res - Format info + 1. SAP Status (1 byte) + + Noti(Unsol) - Format info + 1. Card Status (1 byte) +**/ + +#define OEM_SAP_READER_STATUS 0x03 +/** OEM_SAP_READER_STATUS + Req - Format info + non. + + Res - Format info + 1. Result code (1 byte) + 2. Card reader status (1 byte) + + Noti(Unsol) - Format info + non. +**/ + +#define OEM_SAP_SIM_POWER 0x04 +/** OEM_SAP_SIM_POWER + Req - Format info + 1. MSG ID (1 byte) + + Res - Format info + 1. MSG ID (1 byte) + 2. Result code (1 byte) + + Noti(Unsol) - Format info + non. +**/ + +#define OEM_SAP_TRANSFER_ATR 0x05 +/** OEM_SAP_TRANSFER_ATR + Req - Format info + non. + + Res - Format info + 1. Result code (1 byte) + 2. ATR length (2 byte) + 3. ATR (variables) + + Noti(Unsol) - Format info + non. +**/ + +#define OEM_SAP_TRANSFER_APDU 0x06 +/** OEM_SAP_TRANSFER_APDU + Req - Format info + 1. APDU length(2 byte) + 2. commadn apdu or apdu_7816 (variables) + + Res - Format info + 1. Result code (1 byte) + 2. Res APDU length (2 byte) + 3. Res APDU (variables) + + Noti(Unsol) - Format info + non. +**/ + +#define OEM_SAP_SET_PROTOCOL 0x07 +/** OEM_SAP_SET_PROTOCOL + Req - Format info + 1. Transport protocol (1 byte) + + Res - Format info + 1. Result code (1 byte) + + Noti(Unsol) - Format info + non. +**/ + + +/*MAX_MSG_SIZE */ +#define MAX_MSG_SIZE 512 // 256->512 + +/* MSG_ID Table */ +#define OEM_SAP_CONNECT_REQ 0x00 /*Client -> Server*/ +#define OEM_SAP_CONNECT_RESP 0x01 /*Server -> Client */ +#define OEM_SAP_DISCONNECT_REQ 0x02 /*Client -> Server*/ +#define OEM_SAP_DISCONNECT_RESP 0x03 /*Server -> Client */ +#define OEM_SAP_DISCONNECT_IND 0x04 /*Server -> Client */ +#define OEM_SAP_TRANSFER_APDU_REQ 0x05 /*Client -> Server*/ +#define OEM_SAP_TRANSFER_APDU_RESP 0x06 /*Server -> Client */ +#define OEM_SAP_TRANSFER_ATR_REQ 0x07 /*Client -> Server*/ +#define OEM_SAP_TRANSFER_ATR_RESP 0x08 /*Server -> Client */ +#define OEM_SAP_POWER_SIM_OFF_REQ 0x09 /*Client -> Server*/ +#define OEM_SAP_POWER_SIM_OFF_RESP 0x0A /*Server -> Client */ +#define OEM_SAP_POWER_SIM_ON_REQ 0x0B /*Client -> Server*/ +#define OEM_SAP_POWER_SIM_ON_RESP 0x0C /*Server -> Client */ +#define OEM_SAP_RESET_SIM_REQ 0x0D /*Client -> Server*/ +#define OEM_SAP_RESET_SIM_RESP 0x0E /*Server -> Client */ +#define OEM_SAP_TRANSFER_CARD_READER_STATUS_REQ 0x0F /*Client -> Server*/ +#define OEM_SAP_TRANSFER_CARD_READER_STATUS_RESP 0x10 /*Server -> Client */ +#define OEM_SAP_STATUS_IND 0x11 /*Client -> Server*/ +#define OEM_SAP_ERROR_RESP 0x12 /*Server -> Client */ +#define OEM_SAP_SET_TRANSPORT_PROTOCOL_REQ 0x13 /*Client -> Server*/ +#define OEM_SAP_SET_TRANSPORT_PROTOCOL_RESP 0x14 /*Server -> Client */ + +/*CONNECTIN STATUS */ +#define OEM_SAP_CONNECT_OK 0x00 +#define OEM_SAP_CONNECT_UNABLE_ESTABLISH 0x01 +#define OEM_SAP_CONNECT_NOT_SUPPORT_MAX_SIZE 0x02 +#define OEM_SAP_CONNECT_TOO_SMALL_MAX_SIZE 0x03 + +/*DISCONNECT TYPE */ +#define OEM_SAP_DISCONNECT_TYPE_GRACEFUL 0x00 +#define OEM_SAP_DISCONNECT_TYPE_IMMEDIATE 0x01 + +/*SAP STATUS */ +#define OEM_SAP_STATUS_UNKNOWN 0x00 +#define OEM_SAP_STATUS_NO_SIM 0x01 +#define OEM_SAP_STATUS_NOT_READY 0x02 +#define OEM_SAP_STATUS_READY 0x03 +#define OEM_SAP_STATUS_CONNECTED 0x04 + +/*CARD STATUS */ +#define OEM_SAP_CARD_STATUS_UNKNOWN 0x00 +#define OEM_SAP_CARD_STATUS_RESET 0x01 +#define OEM_SAP_CARD_STATUS_NOT_ACCESSIBLE 0x02 +#define OEM_SAP_CARD_STATUS_REMOVED 0x03 +#define OEM_SAP_CARD_STATUS_INSERTED 0x04 +#define OEM_SAP_CARD_STATUS_RECOVERED 0x05 + +/*RESULT CODE */ +#define OEM_SAP_RESULT_OK 0x00 +#define OEM_SAP_RESULT_NO_REASON 0x01 +#define OEM_SAP_RESULT_CARD_NOT_ACCESSIBLE 0x02 +#define OEM_SAP_RESULT_CARD_ALREADY_POWER_OFF 0x03 +#define OEM_SAP_RESULT_REMOVED 0x04 +#define OEM_SAP_RESULT_ALREADY_POWER_ON 0x05 +#define OEM_SAP_RESULT_DATA_NOT_AVAILABLE 0x06 +#define OEM_SAP_RESULT_NOT_SUPPORT 0x07 + +/*TRANSPORT PROTOCOL*/ +#define OEM_SAP_TRANSPORT_PROTOCOL_T_ZERO 0x00 +#define OEM_SAP_TRANSPORT_PROTOCOL_T_ONE 0x01 + + +typedef struct { + uint8_t func_id; + uint8_t cmd; + uint16_t len; +} __attribute__((packed)) oem_ril_sap_hdr; + +typedef struct { + uint8_t msg_id; +} __attribute__((packed)) ril_sap_req_sap_connect; + + +typedef struct { + uint16_t apdu_len; + uint8_t apdu[MAX_MSG_SIZE]; +} __attribute__((packed)) ril_sap_req_transfer_apdu; + +typedef struct { + uint8_t transport_protocol; +} __attribute__((packed)) ril_sap_req_transport_protocol; + + +typedef struct { + uint8_t msg_id; +} __attribute__((packed)) ril_sap_req_sim_power; + + +typedef struct { + uint8_t msg_id; + uint8_t connection_status; + uint16_t max_msg_size; +} __attribute__((packed)) ril_sap_res_connect; + +typedef struct { + uint8_t sap_status; +} __attribute__((packed)) ril_sap_res_sap_status; + +typedef struct { + uint8_t result_code; + uint16_t atr_len; + uint8_t atr[MAX_MSG_SIZE]; +} __attribute__((packed)) ril_sap_res_transfer_atr; + +typedef struct { + uint8_t result_code; + uint16_t res_apdu_len; + uint8_t res_apdu[MAX_MSG_SIZE]; +} __attribute__((packed)) ril_sap_res_transfer_apdu; + +typedef struct { + uint8_t result_code; +} __attribute__((packed)) ril_sap_res_transport_protocol; + +typedef struct { + uint8_t msg_id; + uint8_t result_code; +} __attribute__((packed)) ril_sap_res_sim_power; + +typedef struct { + uint8_t result_code; + uint8_t card_reader_status; +} __attribute__((packed)) ril_sap_res_card_reader_status; + +typedef struct { + uint8_t disconnect_type; +} __attribute__((packed)) unsol_sap_connect; + +typedef struct { + uint8_t card_status; +} __attribute__((packed)) unsol_sap_status; + +typedef union { + unsol_sap_connect connect; + unsol_sap_status status; +} __attribute__((packed)) unsol_sap_parameters; + +typedef struct { + uint8_t sub_id; + unsol_sap_parameters param; +} __attribute__((packed)) unsol_sap_notification; + + + + +#endif + diff --git a/system.prop b/system.prop new file mode 100755 index 0000000..b2928cb --- /dev/null +++ b/system.prop @@ -0,0 +1,12 @@ +# +# system.prop for smdk4x12 +# +dalvik.vm.dexopt-data-only=1 +rild.libpath=/system/lib/libsec-ril.so +rild.libargs=-d /dev/ttyS0 +ro.sf.hwrotation=270 +ro.sf.lcd_density=213 +ro.lcd_min_brightness=20 +ro.hdcp2.rx=tz + + diff --git a/twrp.fstab b/twrp.fstab new file mode 100644 index 0000000..63a56c8 --- /dev/null +++ b/twrp.fstab @@ -0,0 +1,12 @@ +# mount point fstype device +/efs ext4 /dev/block/mmcblk0p3 flags=display="EFS";backup=1 +/boot emmc /dev/block/mmcblk0p5 +/recovery emmc /dev/block/mmcblk0p6 +/cache ext4 /dev/block/mmcblk0p8 +/system ext4 /dev/block/mmcblk0p9 +/data ext4 /dev/block/mmcblk0p12 length=-16384 +/preload ext4 /dev/block/mmcblk0p10 +/modem emmc /dev/block/mmcblk0p7 flags=display="Modem";backup=1 + +/sdcard datamedia /dev/null +/external_sd vfat /dev/block/mmcblk1p1 flags=display="Micro SDcard";storage;wipeingui;removable -- cgit v1.1