From nobody Sun Feb 8 19:43:52 2026 Received: from xmbghk7.mail.qq.com (xmbghk7.mail.qq.com [43.163.128.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C6D330C606; Sat, 7 Feb 2026 09:42:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=43.163.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770457376; cv=none; b=WNvIxvVOsYPPcVzFXojJDltrwogm5XRfR48bi2BTm1dcV9ksZ6YLMNLctPLwW+7iIqiXXV1e36ASyLMwZOa1Iq3Ke9NypDM6p1zLJE4OpZ3Q2xpP1OetWinHM4B7HHFtZwvkEtBrhac+CURVtM+UGrC1E0JVerAqAI8LzM9stu8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770457376; c=relaxed/simple; bh=mivhbAEpIwXsg5JY5GypZxRuyny3HnzgW0/IhPeC65o=; h=Message-ID:From:To:Cc:Subject:Date:MIME-Version; b=f/Z+03xrRGuCEu4Pv3RgKdsqkz5qV02cssLH9584Tkez7P1BV0qNQ1bJl0LS8cs7OD21CCFa9bTam84/hbTvscLV92OfVydgg5FHACY4YPqb5CGRFYgmyG2FrBi47Xb6N2nLxjE6BENtqsBBjH5QXMLo1VvcE6seiFQ/JxaKomk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=qq.com; spf=pass smtp.mailfrom=qq.com; dkim=pass (1024-bit key) header.d=qq.com header.i=@qq.com header.b=w6Atru6N; arc=none smtp.client-ip=43.163.128.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=qq.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=qq.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=qq.com header.i=@qq.com header.b="w6Atru6N" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512; t=1770457365; bh=U28fsapFNpLzbN5G64boDdaXpuPju6izMWnvTRlD1+4=; h=From:To:Cc:Subject:Date; b=w6Atru6NK9W4Rp/oheI/hxQmCbkLExNp3vUPSyjptUS2oQ9OkOPvzZTyHbcUvNlMy aFXTaeqIEqMZiQzLfzWMXVHisxjjV8yKIirJFyI+QKUhqfma8jUN0lfaeQLfu9/xkv RVioqbUTIeHXsW2uAmZ2hHIuq5uFxbQY4dPvMlCs= Received: from localhost.localdomain ([58.34.102.26]) by newxmesmtplogicsvrszc50-0.qq.com (NewEsmtp) with SMTP id AA987696; Sat, 07 Feb 2026 17:42:41 +0800 X-QQ-mid: xmsmtpt1770457361t05o6f3mj Message-ID: X-QQ-XMAILINFO: MEx+xBdGVwfV+0PXCAnZ07J8RT9bwHwBgv5B5az7y46jpB/yiA8vD2G4jI0gCc EdpMGQrXjfdfHkXGSyTwGRDxZCrHBII+pBPnRAvC/8Teele8jPPewhVvc7hDo1UEnb6x93pm+Se6 XgP8yzmQ+PbkOwy5axiQNC5y5SovWNXTK2xTFHUMvx2SDK8F0tOOSWcilJb4xg6213j0XB6ZRTw5 MZ6+cF5jnRhbmB6o2zhF+47JUii67wpZnZOJE86CaoQ9c4ZUzzXCEuoL83aPhVcFavnSOgiELilH nLFWqSupBjMrAoyP4POQzPFrrWDXngeH7XSaZodRWjXcppFBnENNkRbnqGt++19UujmJFGpVR69p r28g4etZ9rzyXEvsWjEIyTK3DwRgYTs9IgIDOFy6Oa4j/YdzMQ41wCvVQ8sJ/rd4pDXDrsb1d/Cx JQhsj3EEbZQJwJHuKYa3kjaJIARvLX+2KrlKa1e3hBJ5Mxyjpc2eKxEz6E1f5/UxIHYBfN6DJYRV yi5AnRtAMuXbwD4J8zisVRO+cLjS6ooUW8G2tAR7Z8q0KH4+8ihW0wh4AHc0kLUFpTdDMB/YNhuX 8wUglZmgjpRlxqGWtp2KCfZkqAet2u5bprXFhlaX1hZW4t6tUntfM5XMeB4oRa2ucyS9vExfINJZ fD2j4/KmBE3JguFeQM0SezFc6FYPT8Ka7aifbiC60idmtV57Vo6hoeWm6BgulWQEYuz8Yyqrh4hV zkMjmKcbT+fdYNCEpQlH/6o0GAqkO5ZOBMvRtyfZUtxlZNvXh96GjXA06Wm2KNTxjt3SIJYw87w6 n2XJwJmZUrz32gROpFoay0ilx8V+P6AhrwiBt0biaTm4OGmwE5bRLntsOqWowMqZLxde77TlU4Vd SewEkvr7ozMDtno9i0fzfdX98L+YSpz4GT3492nhBBZCtv3JgVohcpQATJzISMc7CAd1eZ0TUhaD IKqrna5jriwdditq91pzWG9mFm04yg70Ch+DLR1rygrpvITUB1rA== X-QQ-XMRINFO: Nq+8W0+stu50tPAe92KXseR0ZZmBTk3gLg== From: 434779359@qq.com To: Jonathan Cameron Cc: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Liam Girdwood , Mark Brown , Linus Walleij , Bartosz Golaszewski , liufulin , Waqar Hameed , linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-gpio@vger.kernel.org Subject: [PATCH] tof: Add VL53L4CX TOF drivers Date: Sat, 7 Feb 2026 17:42:35 +0800 X-OQ-MSGID: <20260207094235.1780679-1-434779359@qq.com> X-Mailer: git-send-email 2.25.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: liufulin This patch adds support for the vl53l4cx tof ic ICs used in Qualcomm reference designs Signed-off-by: liufulin --- drivers/iio/proximity/Kconfig | 10 + drivers/iio/proximity/Makefile | 1 + drivers/iio/proximity/vl53l4cx-i2c.c | 18161 +++++++++++++++++++++++++ 3 files changed, 18172 insertions(+) create mode 100644 drivers/iio/proximity/vl53l4cx-i2c.c diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig index 6070974c2c85..a2fcb39e444e 100644 --- a/drivers/iio/proximity/Kconfig +++ b/drivers/iio/proximity/Kconfig @@ -255,4 +255,14 @@ config AW96103 To compile this driver as a module, choose M here: the module will be called aw96103. =20 +config VL53L4CX_I2C + tristate "STMicroelectronics VL53L0X ToF ranger sensor (I2C)" + depends on I2C + help + Say Y here to build a driver for STMicroelectronics VL53L0X + ToF ranger sensors with i2c interface. + This driver can be used to measure the distance of objects. + To compile this driver as a module, choose M here: the + module will be called vl53l0x-i2c. + endmenu diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile index 152034d38c49..8a682bbed50b 100644 --- a/drivers/iio/proximity/Makefile +++ b/drivers/iio/proximity/Makefile @@ -24,4 +24,5 @@ obj-$(CONFIG_SX9500) +=3D sx9500.o obj-$(CONFIG_VCNL3020) +=3D vcnl3020.o obj-$(CONFIG_VL53L0X_I2C) +=3D vl53l0x-i2c.o obj-$(CONFIG_AW96103) +=3D aw96103.o +obj-$(CONFIG_VL53L4CX_I2C) +=3D vl53l4cx-i2c.o =20 diff --git a/drivers/iio/proximity/vl53l4cx-i2c.c b/drivers/iio/proximity/v= l53l4cx-i2c.c new file mode 100644 index 000000000000..df9ae9786966 --- /dev/null +++ b/drivers/iio/proximity/vl53l4cx-i2c.c @@ -0,0 +1,18161 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for ST VL53L0X FlightSense ToF Ranging Sensor on a i2c bus. + * + * Copyright (C) 2016 STMicroelectronics Imaging Division. + * Copyright (C) 2018 Song Qiang + * Copyright (C) 2020 Ivan Drobyshevskyi + * + * Datasheet available at + * + * + * Default 7-bit i2c slave address 0x29. + * + * TODO: FIFO buffer, continuous mode, range selection, sensor ID check. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define STMVL53LX_DRV_NAME "stmvl53lx" +#define STMVL53LX_SLAVE_ADDR (0x52>>1) + +#define VL_REG_SYSRANGE_START 0x00 + +#define MODI2C_DEBUG 0 + +#if 0 +#define DEBUG 1 +#endif +#if 0 +#define FORCE_CONSOLE_DEBUG +#endif + +extern int stmvl53lx_enable_debug; + +#ifdef DEBUG +# ifdef FORCE_CONSOLE_DEBUG +#define vl53lx_dbgmsg(str, ...) do { \ + if (stmvl53lx_enable_debug) \ + pr_info("%s: " str, __func__, ##__VA_ARGS__); \ +} while (0) +# else +#define vl53lx_dbgmsg(str, ...) do { \ + if (stmvl53lx_enable_debug) \ + pr_debug("%s: " str, __func__, ##__VA_ARGS__); \ +} while (0) +# endif +#else +# define vl53lx_dbgmsg(...) ((void)0) +#endif + +#define WORK_DEBUG 0 +#if WORK_DEBUG +# define work_dbg(msg, ...)\ + printk("[D WK53L1] :" msg "\n", ##__VA_ARGS__) +#else +# define work_dbg(...) ((void)0) +#endif + +#define vl53lx_info(str, args...) \ + pr_info("%s: " str "\n", __func__, ##args) + +#define vl53lx_errmsg(str, args...) \ + pr_err("%s: " str, __func__, ##args) + +#define vl53lx_wanrmsg(str, args...) \ + pr_warn("%s: " str, __func__, ##args) + +#ifndef STMVL53LX_LOG_POLL_TIMING +# define STMVL53LX_LOG_POLL_TIMING 0 +#endif +#ifndef STMVL53LX_LOG_CCI_TIMING +# define STMVL53LX_LOG_CCI_TIMING 0 +#endif + +#define modi2c_warn(fmt, ...)\ + dev_WARN(&i2c_data->client->dev, fmt, ##__VA_ARGS__) + +#define modi2c_err(fmt, ...)\ + dev_err(&i2c_data->client->dev, fmt, ##__VA_ARGS__) + +#if MODI2C_DEBUG +#define modi2c_dbg(fmt, ...)\ + pr_devel("%s "fmt"\n", __func__, ##__VA_ARGS__) +#else +#define modi2c_dbg(...) ((void)0) +#endif + +#define VL_REG_SYSRANGE_MODE_MASK GENMASK(3, 0) +#define VL_REG_SYSRANGE_MODE_SINGLESHOT 0x00 +#define VL_REG_SYSRANGE_MODE_START_STOP BIT(0) +#define VL_REG_SYSRANGE_MODE_BACKTOBACK BIT(1) +#define VL_REG_SYSRANGE_MODE_TIMED BIT(2) +#define VL_REG_SYSRANGE_MODE_HISTOGRAM BIT(3) + +#define VL_REG_SYSTEM_INTERRUPT_CONFIG_GPIO 0x0A +#define VL_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY BIT(2) + +#define VL_REG_SYSTEM_INTERRUPT_CLEAR 0x0B + +#define VL_REG_RESULT_INT_STATUS 0x13 +#define VL_REG_RESULT_RANGE_STATUS 0x14 +#define VL_REG_RESULT_RANGE_STATUS_COMPLETE BIT(0) + +#define VL53LX_FIRMWARE_BOOT_TIME_US 1200 +#define VL53LX_I2C_SLAVE__DEVICE_ADDRESS 0x0001 + +#define VL53LX_NVM_PEAK_RATE_MAP_SAMPLES 25 + +#define VL53LX_MAX_USER_ZONES 5 + +#define VL53LX_MAX_RANGE_RESULTS 4 + +#define VL53LX_MAX_STRING_LENGTH 512 + +#define VL53LX_RTN_SPAD_BUFFER_SIZE 32 + +#define VL53LX_MAX_BIN_SEQUENCE_LENGTH 6 + +#define VL53LX_XTALK_HISTO_BINS 12 + +#define VL53LX_MAX_XTALK_RANGE_RESULTS 5 + +#define VL53LX_BIN_REC_SIZE 6 + +#define VL53LX_MAX_OFFSET_RANGE_RESULTS 3 + +#define VL53LX_TIMING_CONF_A_B_SIZE 2 + +#define VL53LX_HISTOGRAM_BUFFER_SIZE 24 + +#define VL53LX_FRAME_WAIT_EVENT 6 + +#define VL53LX_RANGE_STATUS__RANGE_STATUS_MASK 0x1F +#define VL53LX_RANGE_STATUS__MAX_THRESHOLD_HIT_MASK 0x20 +#define VL53LX_RANGE_STATUS__MIN_THRESHOLD_HIT_MASK 0x40 +#define VL53LX_RANGE_STATUS__GPH_ID_RANGE_STATUS_MASK 0x80 + +#define VL53LX_INTERRUPT_STATUS__INT_STATUS_MASK 0x07 +#define VL53LX_INTERRUPT_STATUS__INT_ERROR_STATUS_MASK 0x18 +#define VL53LX_INTERRUPT_STATUS__GPH_ID_INT_STATUS_MASK 0x20 + +#define VL53LX_MAX_BIN_SEQUENCE_LENGTH 6 +#define VL53LX_MAX_BIN_SEQUENCE_CODE 15 +#define VL53LX_HISTOGRAM_BUFFER_SIZE 24 +#define VL53LX_XTALK_HISTO_BINS 12 + +#define VL53LX_BOOT_COMPLETION_POLLING_TIMEOUT_MS 500 + +#define VL53LX_BOOT_COMPLETION_POLLING_TIMEOUT_MS 500 +#define VL53LX_RANGE_COMPLETION_POLLING_TIMEOUT_MS 2000 +#define VL53LX_TEST_COMPLETION_POLLING_TIMEOUT_MS 60000 + +#define VL53LX_POLLING_DELAY_MS 1 + +#define VL53LX_FIRMWARE__SYSTEM_STATUS 0x00E5 + +#define VL53LX_GROUPEDPARAMETERHOLD_ID_MASK 0x02 + +#define VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES 5 + +#define STMVL53LX_MAX_CCI_XFER_SZ 256 + +#define FDA_MAX_TIMING_BUDGET_US 550000 +#define L4_FDA_MAX_TIMING_BUDGET_US 200000 + +#define WRITE_MULTIPLE_CHUNK_MAX 32 + +#define VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE 0x0083 + +#define VL53LX_DEVICEMEASUREMENTMODE_MODE_MASK 0xF0 +#define VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK 0x0F + +#define VL53LX_MAX_AMBIENT_DMAX_VALUES 5 + +#define VL53LX_PATCH__CTRL 0x0470 + +#define VL53LX_FIRMWARE__ENABLE 0x0085 + +#define VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES 23 + +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0 0x000D + +#define IGNORE_DIVISION_BY_ZERO 0 + +#define IGNORE_XTALK_EXTRACTION_NO_SAMPLE_FAIL 0 +#define IGNORE_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL 0 +#define IGNORE_XTALK_EXTRACTION_NO_SAMPLE_FOR_GRADIENT_WARN 0 +#define IGNORE_XTALK_EXTRACTION_SIGMA_LIMIT_FOR_GRADIENT_WARN 0 +#define IGNORE_XTALK_EXTRACTION_MISSING_SAMPLES_WARN 0 + +#define IGNORE_REF_SPAD_CHAR_NOT_ENOUGH_SPADS 0 +#define IGNORE_REF_SPAD_CHAR_RATE_TOO_HIGH 0 +#define IGNORE_REF_SPAD_CHAR_RATE_TOO_LOW 0 + +#define IGNORE_OFFSET_CAL_MISSING_SAMPLES 0 +#define IGNORE_OFFSET_CAL_SIGMA_TOO_HIGH 0 +#define IGNORE_OFFSET_CAL_RATE_TOO_HIGH 0 +#define IGNORE_OFFSET_CAL_SPAD_COUNT_TOO_LOW 0 + +#define IGNORE_ZONE_CAL_MISSING_SAMPLES 0 +#define IGNORE_ZONE_CAL_SIGMA_TOO_HIGH 0 +#define IGNORE_ZONE_CAL_RATE_TOO_HIGH 0 + +#ifndef SUPPRESS_UNUSED_WARNING +#define SUPPRESS_UNUSED_WARNING(x) ((void) (x)) +#endif + +#define VL53LX_TRACE_LEVEL_NONE 0x00000000 +#define VL53LX_TRACE_LEVEL_ERRORS 0x00000001 +#define VL53LX_TRACE_LEVEL_WARNING 0x00000002 +#define VL53LX_TRACE_LEVEL_INFO 0x00000004 +#define VL53LX_TRACE_LEVEL_DEBUG 0x00000008 +#define VL53LX_TRACE_LEVEL_ALL 0x00000010 +#define VL53LX_TRACE_LEVEL_IGNORE 0x00000020 +#define VL53LX_TRACE_FUNCTION_NONE 0x00000000 +#define VL53LX_TRACE_FUNCTION_I2C 0x00000001 +#define VL53LX_TRACE_FUNCTION_ALL 0x7fffffff +#define VL53LX_TRACE_MODULE_NONE 0x00000000 +#define VL53LX_TRACE_MODULE_API 0x00000001 +#define VL53LX_TRACE_MODULE_CORE 0x00000002 +#define VL53LX_TRACE_MODULE_PROTECTED 0x00000004 +#define VL53LX_TRACE_MODULE_HISTOGRAM 0x00000008 +#define VL53LX_TRACE_MODULE_REGISTERS 0x00000010 +#define VL53LX_TRACE_MODULE_PLATFORM 0x00000020 +#define VL53LX_TRACE_MODULE_NVM 0x00000040 +#define VL53LX_TRACE_MODULE_CALIBRATION_DATA 0x00000080 +#define VL53LX_TRACE_MODULE_NVM_DATA 0x00000100 +#define VL53LX_TRACE_MODULE_HISTOGRAM_DATA 0x00000200 +#define VL53LX_TRACE_MODULE_RANGE_RESULTS_DATA 0x00000400 +#define VL53LX_TRACE_MODULE_XTALK_DATA 0x00000800 +#define VL53LX_TRACE_MODULE_OFFSET_DATA 0x00001000 +#define VL53LX_TRACE_MODULE_DATA_INIT 0x00002000 +#define VL53LX_TRACE_MODULE_REF_SPAD_CHAR 0x00004000 +#define VL53LX_TRACE_MODULE_SPAD_RATE_MAP 0x00008000 +#define VL53LX_TRACE_MODULE_CUSTOMER_API 0x40000000 +#define VL53LX_TRACE_MODULE_ALL 0x7fffffff + +#define DISABLE_WARNINGS() +#define ENABLE_WARNINGS() + +#define IGNORE_STATUS(__FUNCTION_ID__, __ERROR_STATUS_CHECK__, __STATUS__)= \ + do { \ + DISABLE_WARNINGS(); \ + if (__FUNCTION_ID__) { \ + if (__STATUS__ =3D=3D __ERROR_STATUS_CHECK__) { \ + __STATUS__ =3D VL53LX_ERROR_NONE; \ + } \ + } \ + ENABLE_WARNINGS(); \ + } \ + while (0) + +#define VL53LX_COPYSTRING(str, ...) \ + (strncpy(str, ##__VA_ARGS__, VL53LX_MAX_STRING_LENGTH-1)) + +#define VL53LX_RANGESTATUS_NONE 255 + +#define VL53LX_MAX_I2C_XFER_SIZE 256 + +#define STMVL53LX_CFG_MAX_DEV 2 + +#define do_division_u(dividend, divisor) div64_u64(dividend, divisor) +#define do_division_s(dividend, divisor) div64_s64(dividend, divisor) + +#define VL53LX_SPEED_OF_LIGHT_IN_AIR 299704 + +#define VL53LX_SPEED_OF_LIGHT_IN_AIR_DIV_8 (299704 >> 3) + +#define VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES 11 + +#define VL53LX_STATIC_NVM_MANAGED_I2C_INDEX \ + VL53LX_I2C_SLAVE__DEVICE_ADDRESS +#define VL53LX_CUSTOMER_NVM_MANAGED_I2C_INDEX \ + VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0 +#define VL53LX_STATIC_CONFIG_I2C_INDEX \ + VL53LX_DSS_CONFIG__TARGET_TOTAL_RATE_MCPS +#define VL53LX_GENERAL_CONFIG_I2C_INDEX \ + VL53LX_GPH_CONFIG__STREAM_COUNT_UPDATE_VALUE +#define VL53LX_TIMING_CONFIG_I2C_INDEX \ + VL53LX_MM_CONFIG__TIMEOUT_MACROP_A_HI +#define VL53LX_DYNAMIC_CONFIG_I2C_INDEX \ + VL53LX_SYSTEM__GROUPED_PARAMETER_HOLD_0 +#define VL53LX_SYSTEM_CONTROL_I2C_INDEX \ + VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE +#define VL53LX_SYSTEM_RESULTS_I2C_INDEX \ + VL53LX_RESULT__INTERRUPT_STATUS +#define VL53LX_CORE_RESULTS_I2C_INDEX \ + VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0 +#define VL53LX_DEBUG_RESULTS_I2C_INDEX \ + VL53LX_PHASECAL_RESULT__REFERENCE_PHASE +#define VL53LX_NVM_COPY_DATA_I2C_INDEX \ + VL53LX_IDENTIFICATION__MODEL_ID +#define VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_INDEX \ + VL53LX_PREV_SHADOW_RESULT__INTERRUPT_STATUS +#define VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_INDEX \ + VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0 +#define VL53LX_PATCH_DEBUG_I2C_INDEX \ + VL53LX_RESULT__DEBUG_STATUS +#define VL53LX_GPH_GENERAL_CONFIG_I2C_INDEX \ + VL53LX_GPH__SYSTEM__THRESH_RATE_HIGH +#define VL53LX_GPH_STATIC_CONFIG_I2C_INDEX \ + VL53LX_GPH__DSS_CONFIG__ROI_MODE_CONTROL +#define VL53LX_GPH_TIMING_CONFIG_I2C_INDEX \ + VL53LX_GPH__MM_CONFIG__TIMEOUT_MACROP_A_HI +#define VL53LX_FW_INTERNAL_I2C_INDEX \ + VL53LX_FIRMWARE__INTERNAL_STREAM_COUNT_DIV +#define VL53LX_PATCH_RESULTS_I2C_INDEX \ + VL53LX_DSS_CALC__ROI_CTRL +#define VL53LX_SHADOW_SYSTEM_RESULTS_I2C_INDEX \ + VL53LX_SHADOW_PHASECAL_RESULT__VCSEL_START +#define VL53LX_SHADOW_CORE_RESULTS_I2C_INDEX \ + VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0 + +#define CONT_CONTINUE 0 +#define CONT_NEXT_LOOP 1 +#define CONT_RESET 2 + +#define VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES 11 +#define VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES 23 +#define VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES 32 +#define VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES 22 +#define VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES 23 +#define VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES 18 +#define VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES 5 +#define VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES 44 +#define VL53LX_CORE_RESULTS_I2C_SIZE_BYTES 33 +#define VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES 56 +#define VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES 49 +#define VL53LX_PREV_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES 44 +#define VL53LX_PREV_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES 33 +#define VL53LX_PATCH_DEBUG_I2C_SIZE_BYTES 2 +#define VL53LX_GPH_GENERAL_CONFIG_I2C_SIZE_BYTES 5 +#define VL53LX_GPH_STATIC_CONFIG_I2C_SIZE_BYTES 6 +#define VL53LX_GPH_TIMING_CONFIG_I2C_SIZE_BYTES 16 +#define VL53LX_FW_INTERNAL_I2C_SIZE_BYTES 2 +#define VL53LX_PATCH_RESULTS_I2C_SIZE_BYTES 90 +#define VL53LX_SHADOW_SYSTEM_RESULTS_I2C_SIZE_BYTES 82 +#define VL53LX_SHADOW_CORE_RESULTS_I2C_SIZE_BYTES 33 + +#define VL53LX_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION 0x20 + +#define VL53LX_LL_CALIBRATION_DATA_STRUCT_VERSION 0xECAB0102 + +#define VL53LX_CALIBRATION_DATA_STRUCT_VERSION \ + (VL53LX_LL_CALIBRATION_DATA_STRUCT_VERSION + \ + VL53LX_ADDITIONAL_CALIBRATION_DATA_STRUCT_VERSION) + +#define VL53LX_RANGESTATUS_RANGE_VALID 0 +#define VL53LX_RANGESTATUS_SIGMA_FAIL 1 +#define VL53LX_RANGESTATUS_SIGNAL_FAIL 2 +#define VL53LX_RANGESTATUS_RANGE_VALID_MIN_RANGE_CLIPPED 3 +#define VL53LX_RANGESTATUS_OUTOFBOUNDS_FAIL 4 +#define VL53LX_RANGESTATUS_HARDWARE_FAIL 5 +#define VL53LX_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL 6 +#define VL53LX_RANGESTATUS_WRAP_TARGET_FAIL 7 +#define VL53LX_RANGESTATUS_PROCESSING_FAIL 8 +#define VL53LX_RANGESTATUS_XTALK_SIGNAL_FAIL 9 +#define VL53LX_RANGESTATUS_SYNCRONISATION_INT 10 +#define VL53LX_RANGESTATUS_RANGE_VALID_MERGED_PULSE 11 +#define VL53LX_RANGESTATUS_TARGET_PRESENT_LACK_OF_SIGNAL 12 +#define VL53LX_RANGESTATUS_MIN_RANGE_FAIL 13 +#define VL53LX_RANGESTATUS_RANGE_INVALID 14 +#define VL53LX_RANGESTATUS_NONE 255 + +#define VL53LX_Dev_t VL53LX_DevData_t +#define VL53LX_DEV VL53LX_DevData_t * + +#define VL53LXDevDataGet(Dev, field) (Dev->field) +#define VL53LXDevDataSet(Dev, field, data) ((Dev->field) =3D (data)) + +#define VL53LXDevStructGetLLDriverHandle(Dev) (&VL53LXDevDataGet(Dev, LLDa= ta)) +#define VL53LXDevStructGetLLResultsHandle(Dev) (&VL53LXDevDataGet(Dev,\ + llresults)) + +#define VL53LX_SETPARAMETERFIELD(Dev, field, value) \ + (VL53LXDevDataSet(Dev, CurrentParameters.field, value)) + +#define VL53LX_GETPARAMETERFIELD(Dev, field, variable) \ + (variable =3D VL53LXDevDataGet(Dev, CurrentParameters).field) + +#define VL53LX_SETARRAYPARAMETERFIELD(Dev, field, index, value) \ + (VL53LXDevDataSet(Dev, CurrentParameters.field[index], value)) + +#define VL53LX_GETARRAYPARAMETERFIELD(Dev, field, index, variable) \ + (variable =3D VL53LXDevDataGet(Dev, CurrentParameters).field[index]) + +#define VL53LX_SETDEVICESPECIFICPARAMETER(Dev, field, value) \ + (VL53LXDevDataSet(Dev, DeviceSpecificParameters.field, value)) + +#define VL53LX_GETDEVICESPECIFICPARAMETER(Dev, field) \ + (VL53LXDevDataGet(Dev, DeviceSpecificParameters).field) + +#define stvm531_get_max_meas_err(...) 3 +#define stvm531_get_max_stream_err(...) 6 + +#define VL53LX_D_001 8 +#define VL53LX_D_002 0xFFFF +#define VL53LX_D_008 0xFFFF +#define VL53LX_D_003 0xFFFFFF +#define VL53LX_D_007 0xFFFFFFFF +#define VL53LX_D_005 0x7FFFFFFFFF +#define VL53LX_D_009 0xFFFFFFFFFF +#define VL53LX_D_010 0xFFFFFFFFFFFF +#define VL53LX_D_004 0xFFFFFFFFFFFFFF +#define VL53LX_D_006 0x7FFFFFFFFFFFFFFF +#define VL53LX_D_011 0xFFFFFFFFFFFFFFFF + + +typedef uint32_t FixPoint1616_t; + +#define VL53LX_FIXPOINT1616TOFIXPOINT44(Value) ((uint16_t)((Value>>12)&0xF= FFF)) +#define VL53LX_FIXPOINT44TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t= )Value<<12)) + +#define VL53LX_FIXPOINT1616TOFIXPOINT72(Value) ((uint16_t)((Value>>14)&0xF= FFF)) +#define VL53LX_FIXPOINT72TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t= )Value<<14)) + +#define VL53LX_FIXPOINT1616TOFIXPOINT97(Value) ((uint16_t)((Value>>9)&0xFF= FF)) +#define VL53LX_FIXPOINT97TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t= )Value<<9)) + +#define VL53LX_FIXPOINT1616TOFIXPOINT88(Value) ((uint16_t)((Value>>8)&0xFF= FF)) +#define VL53LX_FIXPOINT88TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t= )Value<<8)) + +#define VL53LX_FIXPOINT1616TOFIXPOINT412(Value) ((uint16_t)((Value>>4)&0xF= FFF)) +#define VL53LX_FIXPOINT412TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_= t)Value<<4)) + +#define VL53LX_FIXPOINT1616TOFIXPOINT313(Value) ((uint16_t)((Value>>3)&0xF= FFF)) +#define VL53LX_FIXPOINT313TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_= t)Value<<3)) + +#define VL53LX_FIXPOINT1616TOFIXPOINT08(Value) ((uint8_t)((Value>>8)&0x00F= F)) +#define VL53LX_FIXPOINT08TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t= )Value<<8)) + +#define VL53LX_FIXPOINT1616TOFIXPOINT53(Value) ((uint8_t)((Value>>13)&0x00= FF)) +#define VL53LX_FIXPOINT53TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t= )Value<<13)) + +#define VL53LX_FIXPOINT1616TOFIXPOINT102(Value) ((uint16_t)((Value>>14)&0x= 0FFF)) +#define VL53LX_FIXPOINT102TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_= t)Value<<14)) + +#define VL53LX_FIXPOINT1616TOFIXPOINT142(Value) ((uint16_t)((Value>>14)&0x= FFFF)) +#define VL53LX_FIXPOINT142TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_= t)Value<<14)) + +#define VL53LX_FIXPOINT1616TOFIXPOINT160(Value) ((uint16_t)((Value>>16)&0x= FFFF)) +#define VL53LX_FIXPOINT160TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_= t)Value<<16)) + +#define VL53LX_MAKEUINT16(lsb, msb) ((uint16_t)((((uint16_t)msb)<<8) + (ui= nt16_t)lsb)) + +#define ABNORMAL_STOP_1 1 +#define ABNORMAL_STOP_2 2 +#define ABNORMAL_STOP_3 3 + +#define VL53LX_MISC_DEV_NAME "stmvl53lx_ranging" + +enum __stmv53lx_parameter_name_e { + VL53LX_XTALKENABLE_PAR =3D 2, + VL53LX_POLLDELAY_PAR =3D 10, + VL53LX_TIMINGBUDGET_PAR =3D 11, + VL53LX_DISTANCEMODE_PAR =3D 12, + VL53LX_FORCEDEVICEONEN_PAR =3D 14, + VL53LX_LASTERROR_PAR =3D 15, + VL53LX_OFFSETCORRECTIONMODE_PAR =3D 16, + VL53LX_OPTICALCENTER_PAR =3D 17, + VL53LX_TUNING_PAR =3D 20, + VL53LX_SMUDGECORRECTIONMODE_PAR =3D 21, + VL53LX_ISXTALKVALUECHANGED_PAR =3D 22, +}; +#define stmv53lx_parameter_name_e enum __stmv53lx_parameter_name_e + +struct stmvl53lx_parameter { + uint32_t is_read; + stmv53lx_parameter_name_e name; + int32_t value; + int32_t value2; + int32_t status; +}; + +typedef struct { + uint8_t TopLeftX; + uint8_t TopLeftY; + uint8_t BotRightX; + uint8_t BotRightY; +} VL53LX_UserRoi_t; + +struct stmvl53lx_ioctl_roi_t { + int32_t is_read; + VL53LX_UserRoi_t Roi; +}; + +typedef uint8_t VL53LX_WaitMethod; + +#define VL53LX_WAIT_METHOD_BLOCKING ((VL53LX_WaitMethod) 0) +#define VL53LX_WAIT_METHOD_NON_BLOCKING ((VL53LX_WaitMethod) 1) + +#define VL53LX_RETURN_ARRAY_ONLY 0x01 +#define VL53LX_REFERENCE_ARRAY_ONLY 0x10 +#define VL53LX_BOTH_RETURN_AND_REFERENCE_ARRAYS 0x11 +#define VL53LX_NEITHER_RETURN_AND_REFERENCE_ARRAYS 0x00 +#define VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH 0x00 +#define VL53LX_DEVICEINTERRUPTLEVEL_ACTIV +#define VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_MASK 0x10 +#define VL53LX_POLLING_DELAY_US 1000 +#define VL53LX_SOFTWARE_RESET_DURATION_US 100 +#define VL53LX_FIRMWARE_BOOT_TIME_US 1200 +#define VL53LX_ENABLE_POWERFORCE_SETTLING_TIME_US 250 +#define VL53LX_SPAD_ARRAY_WIDTH 16 +#define VL53LX_SPAD_ARRAY_HEIGHT 16 +#define VL53LX_NVM_SIZE_IN_BYTES 512 +#define VL53LX_NO_OF_SPAD_ENABLES 256 +#define VL53LX_RTN_SPAD_BUFFER_SIZE 32 +#define VL53LX_REF_SPAD_BUFFER_SIZE 6 +#define VL53LX_AMBIENT_WINDOW_VCSEL_PERIODS 256 +#define VL53LX_RANGING_WINDOW_VCSEL_PERIODS 2048 +#define VL53LX_MACRO_PERIOD_VCSEL_PERIODS \ + (VL53LX_AMBIENT_WINDOW_VCSEL_PERIODS + \ + VL53LX_RANGING_WINDOW_VCSEL_PERIODS) +#define VL53LX_MAX_ALLOWED_PHASE 0xFFFF +#define VL53LX_RTN_SPAD_UNITY_TRANSMISSION 0x0100 +#define VL53LX_RTN_SPAD_APERTURE_TRANSMISSION 0x0038 +#define VL53LX_SPAD_TOTAL_COUNT_MAX ((0x01 << 29) - 1) +#define VL53LX_SPAD_TOTAL_COUNT_RES_THRES (0x01 << 24) +#define VL53LX_COUNT_RATE_INTERNAL_MAX ((0x01 << 24) - 1) +#define VL53LX_SPEED_OF_LIGHT_IN_AIR 299704 +#define VL53LX_SPEED_OF_LIGHT_IN_AIR_DIV_8 (299704 >> 3) + +typedef uint8_t VL53LX_DeviceError; + +#define VL53LX_DEVICEERROR_NOUPDATE \ + ((VL53LX_DeviceError) 0) +#define VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE \ + ((VL53LX_DeviceError) 1) +#define VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE \ + ((VL53LX_DeviceError) 2) +#define VL53LX_DEVICEERROR_NOVHVVALUEFOUND \ + ((VL53LX_DeviceError) 3) +#define VL53LX_DEVICEERROR_MSRCNOTARGET \ + ((VL53LX_DeviceError) 4) +#define VL53LX_DEVICEERROR_RANGEPHASECHECK \ + ((VL53LX_DeviceError) 5) +#define VL53LX_DEVICEERROR_SIGMATHRESHOLDCHECK \ + ((VL53LX_DeviceError) 6) +#define VL53LX_DEVICEERROR_PHASECONSISTENCY \ + ((VL53LX_DeviceError) 7) +#define VL53LX_DEVICEERROR_MINCLIP \ + ((VL53LX_DeviceError) 8) +#define VL53LX_DEVICEERROR_RANGECOMPLETE \ + ((VL53LX_DeviceError) 9) +#define VL53LX_DEVICEERROR_ALGOUNDERFLOW \ + ((VL53LX_DeviceError) 10) +#define VL53LX_DEVICEERROR_ALGOOVERFLOW \ + ((VL53LX_DeviceError) 11) +#define VL53LX_DEVICEERROR_RANGEIGNORETHRESHOLD \ + ((VL53LX_DeviceError) 12) +#define VL53LX_DEVICEERROR_USERROICLIP \ + ((VL53LX_DeviceError) 13) +#define VL53LX_DEVICEERROR_REFSPADCHARNOTENOUGHDPADS \ + ((VL53LX_DeviceError) 14) +#define VL53LX_DEVICEERROR_REFSPADCHARMORETHANTARGET \ + ((VL53LX_DeviceError) 15) +#define VL53LX_DEVICEERROR_REFSPADCHARLESSTHANTARGET \ + ((VL53LX_DeviceError) 16) +#define VL53LX_DEVICEERROR_MULTCLIPFAIL \ + ((VL53LX_DeviceError) 17) +#define VL53LX_DEVICEERROR_GPHSTREAMCOUNT0READY \ + ((VL53LX_DeviceError) 18) +#define VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK \ + ((VL53LX_DeviceError) 19) +#define VL53LX_DEVICEERROR_EVENTCONSISTENCY \ + ((VL53LX_DeviceError) 20) +#define VL53LX_DEVICEERROR_MINSIGNALEVENTCHECK \ + ((VL53LX_DeviceError) 21) +#define VL53LX_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE \ + ((VL53LX_DeviceError) 22) +#define VL53LX_DEVICEERROR_PREV_RANGE_NO_TARGETS \ + ((VL53LX_DeviceError) 23) + +#define STMVL53LX_CFG_POLL_DELAY_MS 5 + +#define STMVL53LX_CFG_TIMING_BUDGET_US 30000 + +#define STMVL53LX_CFG_DEFAULT_DISTANCE_MODE VL53LX_DISTANCEMODE_MEDIUM + +#define STMVL53LX_CFG_DEFAULT_CROSSTALK_ENABLE 0 + +#define STMVL53LX_CFG_DEFAULT_OFFSET_CORRECTION_MODE \ + VL53LX_OFFSETCORRECTIONMODE_STANDARD + +#define STMVL53LX_CFG_DEFAULT_DMAX_MODE VL53LX_DMAXMODE_CUSTCAL_DATA + +#define STMVL53LX_CFG_DEFAULT_SMUDGE_CORRECTION_MODE \ + VL53LX_SMUDGE_CORRECTION_NONE + +#define VL53LX_NVM_PEAK_RATE_MAP_SAMPLES 25 + +#define VL53LX_NVM_PEAK_RATE_MAP_WIDTH 5 + +#define VL53LX_NVM_PEAK_RATE_MAP_HEIGHT 5 + +#define VL53LX_DSS_CONTROL__ROI_SUBTRACT 0x20 +#define VL53LX_DSS_CONTROL__ROI_INTERSECT 0x10 + +#define VL53LX_DSS_CONTROL__MODE_DISABLED 0x00 +#define VL53LX_DSS_CONTROL__MODE_TARGET_RATE 0x01 +#define VL53LX_DSS_CONTROL__MODE_EFFSPADS 0x02 +#define VL53LX_DSS_CONTROL__MODE_BLOCKSELECT 0x03 + +#define VL53LX_LL_API_IMPLEMENTATION_VER_MAJOR 1 + +#define VL53LX_LL_API_IMPLEMENTATION_VER_MINOR 1 + +#define VL53LX_LL_API_IMPLEMENTATION_VER_SUB 1 + +#define VL53LX_LL_API_IMPLEMENTATION_VER_REVISION 0 + +#define VL53LX_LL_API_IMPLEMENTATION_VER_STRING "1.1.1" + +#define VL53LX_SOFT_RESET 0x0000 +#define VL53LX_I2C_SLAVE__DEVICE_ADDRESS 0x0001 +#define VL53LX_ANA_CONFIG__VHV_REF_SEL_VDDPIX 0x0002 +#define VL53LX_ANA_CONFIG__VHV_REF_SEL_VQUENCH 0x0003 +#define VL53LX_ANA_CONFIG__REG_AVDD1V2_SEL 0x0004 +#define VL53LX_ANA_CONFIG__FAST_OSC__TRIM 0x0005 +#define VL53LX_OSC_MEASURED__FAST_OSC__FREQUENCY 0x0006 +#define VL53LX_OSC_MEASURED__FAST_OSC__FREQUENCY_HI 0x0006 +#define VL53LX_OSC_MEASURED__FAST_OSC__FREQUENCY_LO 0x0007 +#define VL53LX_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND 0x0008 +#define VL53LX_VHV_CONFIG__COUNT_THRESH 0x0009 +#define VL53LX_VHV_CONFIG__OFFSET 0x000A +#define VL53LX_VHV_CONFIG__INIT 0x000B +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0 0x000D +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_1 0x000E +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_2 0x000F +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_3 0x0010 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_4 0x0011 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_5 0x0012 +#define VL53LX_GLOBAL_CONFIG__REF_EN_START_SELECT 0x0013 +#define VL53LX_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS 0x0014 +#define VL53LX_REF_SPAD_MAN__REF_LOCATION 0x0015 +#define VL53LX_ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS 0x0016 +#define VL53LX_ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS_HI 0x0016 +#define VL53LX_ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS_LO 0x0017 +#define VL53LX_ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS 0x0018 +#define VL53LX_ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS_HI 0x0018 +#define VL53LX_ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS_LO 0x0019 +#define VL53LX_ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS 0x001A +#define VL53LX_ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS_HI 0x001A +#define VL53LX_ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS_LO 0x001B +#define VL53LX_REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS 0x001C +#define VL53LX_REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS_HI 0x001C +#define VL53LX_REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS_LO 0x001D +#define VL53LX_ALGO__PART_TO_PART_RANGE_OFFSET_MM 0x001E +#define VL53LX_ALGO__PART_TO_PART_RANGE_OFFSET_MM_HI 0x001E +#define VL53LX_ALGO__PART_TO_PART_RANGE_OFFSET_MM_LO 0x001F +#define VL53LX_MM_CONFIG__INNER_OFFSET_MM 0x0020 +#define VL53LX_MM_CONFIG__INNER_OFFSET_MM_HI 0x0020 +#define VL53LX_MM_CONFIG__INNER_OFFSET_MM_LO 0x0021 +#define VL53LX_MM_CONFIG__OUTER_OFFSET_MM 0x0022 +#define VL53LX_MM_CONFIG__OUTER_OFFSET_MM_HI 0x0022 +#define VL53LX_MM_CONFIG__OUTER_OFFSET_MM_LO 0x0023 +#define VL53LX_DSS_CONFIG__TARGET_TOTAL_RATE_MCPS 0x0024 +#define VL53LX_DSS_CONFIG__TARGET_TOTAL_RATE_MCPS_HI 0x0024 +#define VL53LX_DSS_CONFIG__TARGET_TOTAL_RATE_MCPS_LO 0x0025 +#define VL53LX_DEBUG__CTRL 0x0026 +#define VL53LX_TEST_MODE__CTRL 0x0027 +#define VL53LX_CLK_GATING__CTRL 0x0028 +#define VL53LX_NVM_BIST__CTRL 0x0029 +#define VL53LX_NVM_BIST__NUM_NVM_WORDS 0x002A +#define VL53LX_NVM_BIST__START_ADDRESS 0x002B +#define VL53LX_HOST_IF__STATUS 0x002C +#define VL53LX_PAD_I2C_HV__CONFIG 0x002D +#define VL53LX_PAD_I2C_HV__EXTSUP_CONFIG 0x002E +#define VL53LX_GPIO_HV_PAD__CTRL 0x002F +#define VL53LX_GPIO_HV_MUX__CTRL 0x0030 +#define VL53LX_GPIO__TIO_HV_STATUS 0x0031 +#define VL53LX_GPIO__FIO_HV_STATUS 0x0032 +#define VL53LX_ANA_CONFIG__SPAD_SEL_PSWIDTH 0x0033 +#define VL53LX_ANA_CONFIG__VCSEL_PULSE_WIDTH_OFFSET 0x0034 +#define VL53LX_ANA_CONFIG__FAST_OSC__CONFIG_CTRL 0x0035 +#define VL53LX_SIGMA_ESTIMATOR__EFFECTIVE_PULSE_WIDTH_NS 0x0036 +#define VL53LX_SIGMA_ESTIMATOR__EFFECTIVE_AMBIENT_WIDTH_NS 0x0037 +#define VL53LX_SIGMA_ESTIMATOR__SIGMA_REF_MM 0x0038 +#define VL53LX_ALGO__CROSSTALK_COMPENSATION_VALID_HEIGHT_MM 0x0039 +#define VL53LX_SPARE_HOST_CONFIG__STATIC_CONFIG_SPARE_0 0x003A +#define VL53LX_SPARE_HOST_CONFIG__STATIC_CONFIG_SPARE_1 0x003B +#define VL53LX_ALGO__RANGE_IGNORE_THRESHOLD_MCPS 0x003C +#define VL53LX_ALGO__RANGE_IGNORE_THRESHOLD_MCPS_HI 0x003C +#define VL53LX_ALGO__RANGE_IGNORE_THRESHOLD_MCPS_LO 0x003D +#define VL53LX_ALGO__RANGE_IGNORE_VALID_HEIGHT_MM 0x003E +#define VL53LX_ALGO__RANGE_MIN_CLIP 0x003F +#define VL53LX_ALGO__CONSISTENCY_CHECK__TOLERANCE 0x0040 +#define VL53LX_SPARE_HOST_CONFIG__STATIC_CONFIG_SPARE_2 0x0041 +#define VL53LX_SD_CONFIG__RESET_STAGES_MSB 0x0042 +#define VL53LX_SD_CONFIG__RESET_STAGES_LSB 0x0043 +#define VL53LX_GPH_CONFIG__STREAM_COUNT_UPDATE_VALUE 0x0044 +#define VL53LX_GLOBAL_CONFIG__STREAM_DIVIDER 0x0045 +#define VL53LX_SYSTEM__INTERRUPT_CONFIG_GPIO 0x0046 +#define VL53LX_CAL_CONFIG__VCSEL_START 0x0047 +#define VL53LX_CAL_CONFIG__REPEAT_RATE 0x0048 +#define VL53LX_CAL_CONFIG__REPEAT_RATE_HI 0x0048 +#define VL53LX_CAL_CONFIG__REPEAT_RATE_LO 0x0049 +#define VL53LX_GLOBAL_CONFIG__VCSEL_WIDTH 0x004A +#define VL53LX_PHASECAL_CONFIG__TIMEOUT_MACROP 0x004B +#define VL53LX_PHASECAL_CONFIG__TARGET 0x004C +#define VL53LX_PHASECAL_CONFIG__OVERRIDE 0x004D +#define VL53LX_DSS_CONFIG__ROI_MODE_CONTROL 0x004F +#define VL53LX_SYSTEM__THRESH_RATE_HIGH 0x0050 +#define VL53LX_SYSTEM__THRESH_RATE_HIGH_HI 0x0050 +#define VL53LX_SYSTEM__THRESH_RATE_HIGH_LO 0x0051 +#define VL53LX_SYSTEM__THRESH_RATE_LOW 0x0052 +#define VL53LX_SYSTEM__THRESH_RATE_LOW_HI 0x0052 +#define VL53LX_SYSTEM__THRESH_RATE_LOW_LO 0x0053 +#define VL53LX_DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT 0x0054 +#define VL53LX_DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT_HI 0x0054 +#define VL53LX_DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT_LO 0x0055 +#define VL53LX_DSS_CONFIG__MANUAL_BLOCK_SELECT 0x0056 +#define VL53LX_DSS_CONFIG__APERTURE_ATTENUATION 0x0057 +#define VL53LX_DSS_CONFIG__MAX_SPADS_LIMIT 0x0058 +#define VL53LX_DSS_CONFIG__MIN_SPADS_LIMIT 0x0059 +#define VL53LX_MM_CONFIG__TIMEOUT_MACROP_A_HI 0x005A +#define VL53LX_MM_CONFIG__TIMEOUT_MACROP_A_LO 0x005B +#define VL53LX_MM_CONFIG__TIMEOUT_MACROP_B_HI 0x005C +#define VL53LX_MM_CONFIG__TIMEOUT_MACROP_B_LO 0x005D +#define VL53LX_RANGE_CONFIG__TIMEOUT_MACROP_A_HI 0x005E +#define VL53LX_RANGE_CONFIG__TIMEOUT_MACROP_A_LO 0x005F +#define VL53LX_RANGE_CONFIG__VCSEL_PERIOD_A 0x0060 +#define VL53LX_RANGE_CONFIG__TIMEOUT_MACROP_B_HI 0x0061 +#define VL53LX_RANGE_CONFIG__TIMEOUT_MACROP_B_LO 0x0062 +#define VL53LX_RANGE_CONFIG__VCSEL_PERIOD_B 0x0063 +#define VL53LX_RANGE_CONFIG__SIGMA_THRESH 0x0064 +#define VL53LX_RANGE_CONFIG__SIGMA_THRESH_HI 0x0064 +#define VL53LX_RANGE_CONFIG__SIGMA_THRESH_LO 0x0065 +#define VL53LX_RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS 0x0066 +#define VL53LX_RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS_HI 0x0066 +#define VL53LX_RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS_LO 0x0067 +#define VL53LX_RANGE_CONFIG__VALID_PHASE_LOW 0x0068 +#define VL53LX_RANGE_CONFIG__VALID_PHASE_HIGH 0x0069 +#define VL53LX_SYSTEM__INTERMEASUREMENT_PERIOD 0x006C +#define VL53LX_SYSTEM__INTERMEASUREMENT_PERIOD_3 0x006C +#define VL53LX_SYSTEM__INTERMEASUREMENT_PERIOD_2 0x006D +#define VL53LX_SYSTEM__INTERMEASUREMENT_PERIOD_1 0x006E +#define VL53LX_SYSTEM__INTERMEASUREMENT_PERIOD_0 0x006F +#define VL53LX_SYSTEM__FRACTIONAL_ENABLE 0x0070 +#define VL53LX_SYSTEM__GROUPED_PARAMETER_HOLD_0 0x0071 +#define VL53LX_SYSTEM__THRESH_HIGH 0x0072 +#define VL53LX_SYSTEM__THRESH_HIGH_HI 0x0072 +#define VL53LX_SYSTEM__THRESH_HIGH_LO 0x0073 +#define VL53LX_SYSTEM__THRESH_LOW 0x0074 +#define VL53LX_SYSTEM__THRESH_LOW_HI 0x0074 +#define VL53LX_SYSTEM__THRESH_LOW_LO 0x0075 +#define VL53LX_SYSTEM__ENABLE_XTALK_PER_QUADRANT 0x0076 +#define VL53LX_SYSTEM__SEED_CONFIG 0x0077 +#define VL53LX_SD_CONFIG__WOI_SD0 0x0078 +#define VL53LX_SD_CONFIG__WOI_SD1 0x0079 +#define VL53LX_SD_CONFIG__INITIAL_PHASE_SD0 0x007A +#define VL53LX_SD_CONFIG__INITIAL_PHASE_SD1 0x007B +#define VL53LX_SYSTEM__GROUPED_PARAMETER_HOLD_1 0x007C +#define VL53LX_SD_CONFIG__FIRST_ORDER_SELECT 0x007D +#define VL53LX_SD_CONFIG__QUANTIFIER 0x007E +#define VL53LX_ROI_CONFIG__USER_ROI_CENTRE_SPAD 0x007F +#define VL53LX_ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE 0x0080 +#define VL53LX_SYSTEM__SEQUENCE_CONFIG 0x0081 +#define VL53LX_SYSTEM__GROUPED_PARAMETER_HOLD 0x0082 +#define VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE 0x0083 +#define VL53LX_SYSTEM__STREAM_COUNT_CTRL 0x0084 +#define VL53LX_FIRMWARE__ENABLE 0x0085 +#define VL53LX_SYSTEM__INTERRUPT_CLEAR 0x0086 +#define VL53LX_SYSTEM__MODE_START 0x0087 +#define VL53LX_RESULT__INTERRUPT_STATUS 0x0088 +#define VL53LX_RESULT__RANGE_STATUS 0x0089 +#define VL53LX_RESULT__REPORT_STATUS 0x008A +#define VL53LX_RESULT__STREAM_COUNT 0x008B +#define VL53LX_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0 0x008C +#define VL53LX_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_HI 0x008C +#define VL53LX_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_LO 0x008D +#define VL53LX_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0 0x008E +#define VL53LX_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_HI 0x008E +#define VL53LX_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_LO 0x008F +#define VL53LX_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0 0x0090 +#define VL53LX_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_HI 0x0090 +#define VL53LX_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_LO 0x0091 +#define VL53LX_RESULT__SIGMA_SD0 0x0092 +#define VL53LX_RESULT__SIGMA_SD0_HI 0x0092 +#define VL53LX_RESULT__SIGMA_SD0_LO 0x0093 +#define VL53LX_RESULT__PHASE_SD0 0x0094 +#define VL53LX_RESULT__PHASE_SD0_HI 0x0094 +#define VL53LX_RESULT__PHASE_SD0_LO 0x0095 +#define VL53LX_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 0x0096 +#define VL53LX_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_HI 0x0096 +#define VL53LX_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_LO 0x0097 +#define VL53LX_PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 0x0098 +#define VL53LX__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_HI 0x0= 098 +#define VL53LX___PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_LO 0x= 0099 +#define VL53LX_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0 0x009A +#define VL53LX_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_HI 0x009A +#define VL53LX_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_LO 0x009B +#define VL53LX_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0 0x009C +#define VL53LX_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_HI 0x009C +#define VL53LX_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_LO 0x009D +#define VL53LX_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0 0x009E +#define VL53LX_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_HI 0x009E +#define VL53LX_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_LO 0x009F +#define VL53LX_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1 0x00A0 +#define VL53LX_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_HI 0x00A0 +#define VL53LX_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_LO 0x00A1 +#define VL53LX_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1 0x00A2 +#define VL53LX_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_HI 0x00A2 +#define VL53LX_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_LO 0x00A3 +#define VL53LX_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1 0x00A4 +#define VL53LX_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_HI 0x00A4 +#define VL53LX_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_LO 0x00A5 +#define VL53LX_RESULT__SIGMA_SD1 0x00A6 +#define VL53LX_RESULT__SIGMA_SD1_HI 0x00A6 +#define VL53LX_RESULT__SIGMA_SD1_LO 0x00A7 +#define VL53LX_RESULT__PHASE_SD1 0x00A8 +#define VL53LX_RESULT__PHASE_SD1_HI 0x00A8 +#define VL53LX_RESULT__PHASE_SD1_LO 0x00A9 +#define VL53LX_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1 0x00AA +#define VL53LX_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_HI 0x00AA +#define VL53LX_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_LO 0x00AB +#define VL53LX_RESULT__SPARE_0_SD1 0x00AC +#define VL53LX_RESULT__SPARE_0_SD1_HI 0x00AC +#define VL53LX_RESULT__SPARE_0_SD1_LO 0x00AD +#define VL53LX_RESULT__SPARE_1_SD1 0x00AE +#define VL53LX_RESULT__SPARE_1_SD1_HI 0x00AE +#define VL53LX_RESULT__SPARE_1_SD1_LO 0x00AF +#define VL53LX_RESULT__SPARE_2_SD1 0x00B0 +#define VL53LX_RESULT__SPARE_2_SD1_HI 0x00B0 +#define VL53LX_RESULT__SPARE_2_SD1_LO 0x00B1 +#define VL53LX_RESULT__SPARE_3_SD1 0x00B2 +#define VL53LX_RESULT__THRESH_INFO 0x00B3 +#define VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0 0x00B4 +#define VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_3 0x00B4 +#define VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_2 0x00B5 +#define VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_1 0x00B6 +#define VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_0 0x00B7 +#define VL53LX_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0 0x00B8 +#define VL53LX_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_3 0x00B8 +#define VL53LX_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_2 0x00B9 +#define VL53LX_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_1 0x00BA +#define VL53LX_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_0 0x00BB +#define VL53LX_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0 0x00BC +#define VL53LX_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_3 0x00BC +#define VL53LX_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_2 0x00BD +#define VL53LX_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_1 0x00BE +#define VL53LX_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_0 0x00BF +#define VL53LX_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0 0x00C0 +#define VL53LX_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_3 0x00C0 +#define VL53LX_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_2 0x00C1 +#define VL53LX_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_1 0x00C2 +#define VL53LX_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_0 0x00C3 +#define VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1 0x00C4 +#define VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_3 0x00C4 +#define VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_2 0x00C5 +#define VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_1 0x00C6 +#define VL53LX_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_0 0x00C7 +#define VL53LX_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1 0x00C8 +#define VL53LX_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_3 0x00C8 +#define VL53LX_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_2 0x00C9 +#define VL53LX_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_1 0x00CA +#define VL53LX_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_0 0x00CB +#define VL53LX_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1 0x00CC +#define VL53LX_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_3 0x00CC +#define VL53LX_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_2 0x00CD +#define VL53LX_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_1 0x00CE +#define VL53LX_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_0 0x00CF +#define VL53LX_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1 0x00D0 +#define VL53LX_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_3 0x00D0 +#define VL53LX_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_2 0x00D1 +#define VL53LX_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_1 0x00D2 +#define VL53LX_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_0 0x00D3 +#define VL53LX_RESULT_CORE__SPARE_0 0x00D4 +#define VL53LX_PHASECAL_RESULT__REFERENCE_PHASE 0x00D6 +#define VL53LX_PHASECAL_RESULT__REFERENCE_PHASE_HI 0x00D6 +#define VL53LX_PHASECAL_RESULT__REFERENCE_PHASE_LO 0x00D7 +#define VL53LX_PHASECAL_RESULT__VCSEL_START 0x00D8 +#define VL53LX_REF_SPAD_CHAR_RESULT__NUM_ACTUAL_REF_SPADS 0x00D9 +#define VL53LX_REF_SPAD_CHAR_RESULT__REF_LOCATION 0x00DA +#define VL53LX_VHV_RESULT__COLDBOOT_STATUS 0x00DB +#define VL53LX_VHV_RESULT__SEARCH_RESULT 0x00DC +#define VL53LX_VHV_RESULT__LATEST_SETTING 0x00DD +#define VL53LX_RESULT__OSC_CALIBRATE_VAL 0x00DE +#define VL53LX_RESULT__OSC_CALIBRATE_VAL_HI 0x00DE +#define VL53LX_RESULT__OSC_CALIBRATE_VAL_LO 0x00DF +#define VL53LX_ANA_CONFIG__POWERDOWN_GO1 0x00E0 +#define VL53LX_ANA_CONFIG__REF_BG_CTRL 0x00E1 +#define VL53LX_ANA_CONFIG__REGDVDD1V2_CTRL 0x00E2 +#define VL53LX_ANA_CONFIG__OSC_SLOW_CTRL 0x00E3 +#define VL53LX_TEST_MODE__STATUS 0x00E4 +#define VL53LX_FIRMWARE__SYSTEM_STATUS 0x00E5 +#define VL53LX_FIRMWARE__MODE_STATUS 0x00E6 +#define VL53LX_FIRMWARE__SECONDARY_MODE_STATUS 0x00E7 +#define VL53LX_FIRMWARE__CAL_REPEAT_RATE_COUNTER 0x00E8 +#define VL53LX_FIRMWARE__CAL_REPEAT_RATE_COUNTER_HI 0x00E8 +#define VL53LX_FIRMWARE__CAL_REPEAT_RATE_COUNTER_LO 0x00E9 +#define VL53LX_FIRMWARE__HISTOGRAM_BIN 0x00EA +#define VL53LX_GPH__SYSTEM__THRESH_HIGH 0x00EC +#define VL53LX_GPH__SYSTEM__THRESH_HIGH_HI 0x00EC +#define VL53LX_GPH__SYSTEM__THRESH_HIGH_LO 0x00ED +#define VL53LX_GPH__SYSTEM__THRESH_LOW 0x00EE +#define VL53LX_GPH__SYSTEM__THRESH_LOW_HI 0x00EE +#define VL53LX_GPH__SYSTEM__THRESH_LOW_LO 0x00EF +#define VL53LX_GPH__SYSTEM__ENABLE_XTALK_PER_QUADRANT 0x00F0 +#define VL53LX_GPH__SPARE_0 0x00F1 +#define VL53LX_GPH__SD_CONFIG__WOI_SD0 0x00F2 +#define VL53LX_GPH__SD_CONFIG__WOI_SD1 0x00F3 +#define VL53LX_GPH__SD_CONFIG__INITIAL_PHASE_SD0 0x00F4 +#define VL53LX_GPH__SD_CONFIG__INITIAL_PHASE_SD1 0x00F5 +#define VL53LX_GPH__SD_CONFIG__FIRST_ORDER_SELECT 0x00F6 +#define VL53LX_GPH__SD_CONFIG__QUANTIFIER 0x00F7 +#define VL53LX_GPH__ROI_CONFIG__USER_ROI_CENTRE_SPAD 0x00F8 +#define VL53LX_GPH__ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE 0x00F9 +#define VL53LX_GPH__SYSTEM__SEQUENCE_CONFIG 0x00FA +#define VL53LX_GPH__GPH_ID 0x00FB +#define VL53LX_SYSTEM__INTERRUPT_SET 0x00FC +#define VL53LX_INTERRUPT_MANAGER__ENABLES 0x00FD +#define VL53LX_INTERRUPT_MANAGER__CLEAR 0x00FE +#define VL53LX_INTERRUPT_MANAGER__STATUS 0x00FF +#define VL53LX_MCU_TO_HOST_BANK__WR_ACCESS_EN 0x0100 +#define VL53LX_POWER_MANAGEMENT__GO1_RESET_STATUS 0x0101 +#define VL53LX_PAD_STARTUP_MODE__VALUE_RO 0x0102 +#define VL53LX_PAD_STARTUP_MODE__VALUE_CTRL 0x0103 +#define VL53LX_PLL_PERIOD_US 0x0104 +#define VL53LX_PLL_PERIOD_US_3 0x0104 +#define VL53LX_PLL_PERIOD_US_2 0x0105 +#define VL53LX_PLL_PERIOD_US_1 0x0106 +#define VL53LX_PLL_PERIOD_US_0 0x0107 +#define VL53LX_INTERRUPT_SCHEDULER__DATA_OUT 0x0108 +#define VL53LX_INTERRUPT_SCHEDULER__DATA_OUT_3 0x0108 +#define VL53LX_INTERRUPT_SCHEDULER__DATA_OUT_2 0x0109 +#define VL53LX_INTERRUPT_SCHEDULER__DATA_OUT_1 0x010A +#define VL53LX_INTERRUPT_SCHEDULER__DATA_OUT_0 0x010B +#define VL53LX_NVM_BIST__COMPLETE 0x010C +#define VL53LX_NVM_BIST__STATUS 0x010D +#define VL53LX_IDENTIFICATION__MODEL_ID 0x010F +#define VL53LX_IDENTIFICATION__MODULE_TYPE 0x0110 +#define VL53LX_IDENTIFICATION__REVISION_ID 0x0111 +#define VL53LX_IDENTIFICATION__MODULE_ID 0x0112 +#define VL53LX_IDENTIFICATION__MODULE_ID_HI 0x0112 +#define VL53LX_IDENTIFICATION__MODULE_ID_LO 0x0113 +#define VL53LX_ANA_CONFIG__FAST_OSC__TRIM_MAX 0x0114 +#define VL53LX_ANA_CONFIG__FAST_OSC__FREQ_SET 0x0115 +#define VL53LX_ANA_CONFIG__VCSEL_TRIM 0x0116 +#define VL53LX_ANA_CONFIG__VCSEL_SELION 0x0117 +#define VL53LX_ANA_CONFIG__VCSEL_SELION_MAX 0x0118 +#define VL53LX_PROTECTED_LASER_SAFETY__LOCK_BIT 0x0119 +#define VL53LX_LASER_SAFETY__KEY 0x011A +#define VL53LX_LASER_SAFETY__KEY_RO 0x011B +#define VL53LX_LASER_SAFETY__CLIP 0x011C +#define VL53LX_LASER_SAFETY__MULT 0x011D +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_0 0x011E +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_1 0x011F +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_2 0x0120 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_3 0x0121 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_4 0x0122 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_5 0x0123 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_6 0x0124 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_7 0x0125 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_8 0x0126 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_9 0x0127 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_10 0x0128 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_11 0x0129 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_12 0x012A +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_13 0x012B +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_14 0x012C +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_15 0x012D +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_16 0x012E +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_17 0x012F +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_18 0x0130 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_19 0x0131 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_20 0x0132 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_21 0x0133 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_22 0x0134 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_23 0x0135 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_24 0x0136 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_25 0x0137 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_26 0x0138 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_27 0x0139 +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_28 0x013A +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_29 0x013B +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_30 0x013C +#define VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RTN_31 0x013D +#define VL53LX_ROI_CONFIG__MODE_ROI_CENTRE_SPAD 0x013E +#define VL53LX_ROI_CONFIG__MODE_ROI_XY_SIZE 0x013F +#define VL53LX_GO2_HOST_BANK_ACCESS__OVERRIDE 0x0300 +#define VL53LX_MCU_UTIL_MULTIPLIER__MULTIPLICAND 0x0400 +#define VL53LX_MCU_UTIL_MULTIPLIER__MULTIPLICAND_3 0x0400 +#define VL53LX_MCU_UTIL_MULTIPLIER__MULTIPLICAND_2 0x0401 +#define VL53LX_MCU_UTIL_MULTIPLIER__MULTIPLICAND_1 0x0402 +#define VL53LX_MCU_UTIL_MULTIPLIER__MULTIPLICAND_0 0x0403 +#define VL53LX_MCU_UTIL_MULTIPLIER__MULTIPLIER 0x0404 +#define VL53LX_MCU_UTIL_MULTIPLIER__MULTIPLIER_3 0x0404 +#define VL53LX_MCU_UTIL_MULTIPLIER__MULTIPLIER_2 0x0405 +#define VL53LX_MCU_UTIL_MULTIPLIER__MULTIPLIER_1 0x0406 +#define VL53LX_MCU_UTIL_MULTIPLIER__MULTIPLIER_0 0x0407 +#define VL53LX_MCU_UTIL_MULTIPLIER__PRODUCT_HI 0x0408 +#define VL53LX_MCU_UTIL_MULTIPLIER__PRODUCT_HI_3 0x0408 +#define VL53LX_MCU_UTIL_MULTIPLIER__PRODUCT_HI_2 0x0409 +#define VL53LX_MCU_UTIL_MULTIPLIER__PRODUCT_HI_1 0x040A +#define VL53LX_MCU_UTIL_MULTIPLIER__PRODUCT_HI_0 0x040B +#define VL53LX_MCU_UTIL_MULTIPLIER__PRODUCT_LO 0x040C +#define VL53LX_MCU_UTIL_MULTIPLIER__PRODUCT_LO_3 0x040C +#define VL53LX_MCU_UTIL_MULTIPLIER__PRODUCT_LO_2 0x040D +#define VL53LX_MCU_UTIL_MULTIPLIER__PRODUCT_LO_1 0x040E +#define VL53LX_MCU_UTIL_MULTIPLIER__PRODUCT_LO_0 0x040F +#define VL53LX_MCU_UTIL_MULTIPLIER__START 0x0410 +#define VL53LX_MCU_UTIL_MULTIPLIER__STATUS 0x0411 +#define VL53LX_MCU_UTIL_DIVIDER__START 0x0412 +#define VL53LX_MCU_UTIL_DIVIDER__STATUS 0x0413 +#define VL53LX_MCU_UTIL_DIVIDER__DIVIDEND 0x0414 +#define VL53LX_MCU_UTIL_DIVIDER__DIVIDEND_3 0x0414 +#define VL53LX_MCU_UTIL_DIVIDER__DIVIDEND_2 0x0415 +#define VL53LX_MCU_UTIL_DIVIDER__DIVIDEND_1 0x0416 +#define VL53LX_MCU_UTIL_DIVIDER__DIVIDEND_0 0x0417 +#define VL53LX_MCU_UTIL_DIVIDER__DIVISOR 0x0418 +#define VL53LX_MCU_UTIL_DIVIDER__DIVISOR_3 0x0418 +#define VL53LX_MCU_UTIL_DIVIDER__DIVISOR_2 0x0419 +#define VL53LX_MCU_UTIL_DIVIDER__DIVISOR_1 0x041A +#define VL53LX_MCU_UTIL_DIVIDER__DIVISOR_0 0x041B +#define VL53LX_MCU_UTIL_DIVIDER__QUOTIENT 0x041C +#define VL53LX_MCU_UTIL_DIVIDER__QUOTIENT_3 0x041C +#define VL53LX_MCU_UTIL_DIVIDER__QUOTIENT_2 0x041D +#define VL53LX_MCU_UTIL_DIVIDER__QUOTIENT_1 0x041E +#define VL53LX_MCU_UTIL_DIVIDER__QUOTIENT_0 0x041F +#define VL53LX_TIMER0__VALUE_IN 0x0420 +#define VL53LX_TIMER0__VALUE_IN_3 0x0420 +#define VL53LX_TIMER0__VALUE_IN_2 0x0421 +#define VL53LX_TIMER0__VALUE_IN_1 0x0422 +#define VL53LX_TIMER0__VALUE_IN_0 0x0423 +#define VL53LX_TIMER1__VALUE_IN 0x0424 +#define VL53LX_TIMER1__VALUE_IN_3 0x0424 +#define VL53LX_TIMER1__VALUE_IN_2 0x0425 +#define VL53LX_TIMER1__VALUE_IN_1 0x0426 +#define VL53LX_TIMER1__VALUE_IN_0 0x0427 +#define VL53LX_TIMER0__CTRL 0x0428 +#define VL53LX_TIMER1__CTRL 0x0429 +#define VL53LX_MCU_GENERAL_PURPOSE__GP_0 0x042C +#define VL53LX_MCU_GENERAL_PURPOSE__GP_1 0x042D +#define VL53LX_MCU_GENERAL_PURPOSE__GP_2 0x042E +#define VL53LX_MCU_GENERAL_PURPOSE__GP_3 0x042F +#define VL53LX_MCU_RANGE_CALC__CONFIG 0x0430 +#define VL53LX_MCU_RANGE_CALC__OFFSET_CORRECTED_RANGE 0x0432 +#define VL53LX_MCU_RANGE_CALC__OFFSET_CORRECTED_RANGE_HI 0x0432 +#define VL53LX_MCU_RANGE_CALC__OFFSET_CORRECTED_RANGE_LO 0x0433 +#define VL53LX_MCU_RANGE_CALC__SPARE_4 0x0434 +#define VL53LX_MCU_RANGE_CALC__SPARE_4_3 0x0434 +#define VL53LX_MCU_RANGE_CALC__SPARE_4_2 0x0435 +#define VL53LX_MCU_RANGE_CALC__SPARE_4_1 0x0436 +#define VL53LX_MCU_RANGE_CALC__SPARE_4_0 0x0437 +#define VL53LX_MCU_RANGE_CALC__AMBIENT_DURATION_PRE_CALC 0x0438 +#define VL53LX_MCU_RANGE_CALC__AMBIENT_DURATION_PRE_CALC_HI 0x0438 +#define VL53LX_MCU_RANGE_CALC__AMBIENT_DURATION_PRE_CALC_LO 0x0439 +#define VL53LX_MCU_RANGE_CALC__ALGO_VCSEL_PERIOD 0x043C +#define VL53LX_MCU_RANGE_CALC__SPARE_5 0x043D +#define VL53LX_MCU_RANGE_CALC__ALGO_TOTAL_PERIODS 0x043E +#define VL53LX_MCU_RANGE_CALC__ALGO_TOTAL_PERIODS_HI 0x043E +#define VL53LX_MCU_RANGE_CALC__ALGO_TOTAL_PERIODS_LO 0x043F +#define VL53LX_MCU_RANGE_CALC__ALGO_ACCUM_PHASE 0x0440 +#define VL53LX_MCU_RANGE_CALC__ALGO_ACCUM_PHASE_3 0x0440 +#define VL53LX_MCU_RANGE_CALC__ALGO_ACCUM_PHASE_2 0x0441 +#define VL53LX_MCU_RANGE_CALC__ALGO_ACCUM_PHASE_1 0x0442 +#define VL53LX_MCU_RANGE_CALC__ALGO_ACCUM_PHASE_0 0x0443 +#define VL53LX_MCU_RANGE_CALC__ALGO_SIGNAL_EVENTS 0x0444 +#define VL53LX_MCU_RANGE_CALC__ALGO_SIGNAL_EVENTS_3 0x0444 +#define VL53LX_MCU_RANGE_CALC__ALGO_SIGNAL_EVENTS_2 0x0445 +#define VL53LX_MCU_RANGE_CALC__ALGO_SIGNAL_EVENTS_1 0x0446 +#define VL53LX_MCU_RANGE_CALC__ALGO_SIGNAL_EVENTS_0 0x0447 +#define VL53LX_MCU_RANGE_CALC__ALGO_AMBIENT_EVENTS 0x0448 +#define VL53LX_MCU_RANGE_CALC__ALGO_AMBIENT_EVENTS_3 0x0448 +#define VL53LX_MCU_RANGE_CALC__ALGO_AMBIENT_EVENTS_2 0x0449 +#define VL53LX_MCU_RANGE_CALC__ALGO_AMBIENT_EVENTS_1 0x044A +#define VL53LX_MCU_RANGE_CALC__ALGO_AMBIENT_EVENTS_0 0x044B +#define VL53LX_MCU_RANGE_CALC__SPARE_6 0x044C +#define VL53LX_MCU_RANGE_CALC__SPARE_6_HI 0x044C +#define VL53LX_MCU_RANGE_CALC__SPARE_6_LO 0x044D +#define VL53LX_MCU_RANGE_CALC__ALGO_ADJUST_VCSEL_PERIOD 0x044E +#define VL53LX_MCU_RANGE_CALC__ALGO_ADJUST_VCSEL_PERIOD_HI 0x044E +#define VL53LX_MCU_RANGE_CALC__ALGO_ADJUST_VCSEL_PERIOD_LO 0x044F +#define VL53LX_MCU_RANGE_CALC__NUM_SPADS 0x0450 +#define VL53LX_MCU_RANGE_CALC__NUM_SPADS_HI 0x0450 +#define VL53LX_MCU_RANGE_CALC__NUM_SPADS_LO 0x0451 +#define VL53LX_MCU_RANGE_CALC__PHASE_OUTPUT 0x0452 +#define VL53LX_MCU_RANGE_CALC__PHASE_OUTPUT_HI 0x0452 +#define VL53LX_MCU_RANGE_CALC__PHASE_OUTPUT_LO 0x0453 +#define VL53LX_MCU_RANGE_CALC__RATE_PER_SPAD_MCPS 0x0454 +#define VL53LX_MCU_RANGE_CALC__RATE_PER_SPAD_MCPS_3 0x0454 +#define VL53LX_MCU_RANGE_CALC__RATE_PER_SPAD_MCPS_2 0x0455 +#define VL53LX_MCU_RANGE_CALC__RATE_PER_SPAD_MCPS_1 0x0456 +#define VL53LX_MCU_RANGE_CALC__RATE_PER_SPAD_MCPS_0 0x0457 +#define VL53LX_MCU_RANGE_CALC__SPARE_7 0x0458 +#define VL53LX_MCU_RANGE_CALC__SPARE_8 0x0459 +#define VL53LX_MCU_RANGE_CALC__PEAK_SIGNAL_RATE_MCPS 0x045A +#define VL53LX_MCU_RANGE_CALC__PEAK_SIGNAL_RATE_MCPS_HI 0x045A +#define VL53LX_MCU_RANGE_CALC__PEAK_SIGNAL_RATE_MCPS_LO 0x045B +#define VL53LX_MCU_RANGE_CALC__AVG_SIGNAL_RATE_MCPS 0x045C +#define VL53LX_MCU_RANGE_CALC__AVG_SIGNAL_RATE_MCPS_HI 0x045C +#define VL53LX_MCU_RANGE_CALC__AVG_SIGNAL_RATE_MCPS_LO 0x045D +#define VL53LX_MCU_RANGE_CALC__AMBIENT_RATE_MCPS 0x045E +#define VL53LX_MCU_RANGE_CALC__AMBIENT_RATE_MCPS_HI 0x045E +#define VL53LX_MCU_RANGE_CALC__AMBIENT_RATE_MCPS_LO 0x045F +#define VL53LX_MCU_RANGE_CALC__XTALK 0x0460 +#define VL53LX_MCU_RANGE_CALC__XTALK_HI 0x0460 +#define VL53LX_MCU_RANGE_CALC__XTALK_LO 0x0461 +#define VL53LX_MCU_RANGE_CALC__CALC_STATUS 0x0462 +#define VL53LX_MCU_RANGE_CALC__DEBUG 0x0463 +#define VL53LX_MCU_RANGE_CALC__PEAK_SIGNAL_RATE_XTALK_CORR_MCPS 0x0464 +#define VL53LX_MCU_RANGE_CALC__PEAK_SIGNAL_RATE_XTALK_CORR_MCPS_HI 0x0464 +#define VL53LX_MCU_RANGE_CALC__PEAK_SIGNAL_RATE_XTALK_CORR_MCPS_LO 0x0465 +#define VL53LX_MCU_RANGE_CALC__SPARE_0 0x0468 +#define VL53LX_MCU_RANGE_CALC__SPARE_1 0x0469 +#define VL53LX_MCU_RANGE_CALC__SPARE_2 0x046A +#define VL53LX_MCU_RANGE_CALC__SPARE_3 0x046B +#define VL53LX_PATCH__CTRL 0x0470 +#define VL53LX_PATCH__JMP_ENABLES 0x0472 +#define VL53LX_PATCH__JMP_ENABLES_HI 0x0472 +#define VL53LX_PATCH__JMP_ENABLES_LO 0x0473 +#define VL53LX_PATCH__DATA_ENABLES 0x0474 +#define VL53LX_PATCH__DATA_ENABLES_HI 0x0474 +#define VL53LX_PATCH__DATA_ENABLES_LO 0x0475 +#define VL53LX_PATCH__OFFSET_0 0x0476 +#define VL53LX_PATCH__OFFSET_0_HI 0x0476 +#define VL53LX_PATCH__OFFSET_0_LO 0x0477 +#define VL53LX_PATCH__OFFSET_1 0x0478 +#define VL53LX_PATCH__OFFSET_1_HI 0x0478 +#define VL53LX_PATCH__OFFSET_1_LO 0x0479 +#define VL53LX_PATCH__OFFSET_2 0x047A +#define VL53LX_PATCH__OFFSET_2_HI 0x047A +#define VL53LX_PATCH__OFFSET_2_LO 0x047B +#define VL53LX_PATCH__OFFSET_3 0x047C +#define VL53LX_PATCH__OFFSET_3_HI 0x047C +#define VL53LX_PATCH__OFFSET_3_LO 0x047D +#define VL53LX_PATCH__OFFSET_4 0x047E +#define VL53LX_PATCH__OFFSET_4_HI 0x047E +#define VL53LX_PATCH__OFFSET_4_LO 0x047F +#define VL53LX_PATCH__OFFSET_5 0x0480 +#define VL53LX_PATCH__OFFSET_5_HI 0x0480 +#define VL53LX_PATCH__OFFSET_5_LO 0x0481 +#define VL53LX_PATCH__OFFSET_6 0x0482 +#define VL53LX_PATCH__OFFSET_6_HI 0x0482 +#define VL53LX_PATCH__OFFSET_6_LO 0x0483 +#define VL53LX_PATCH__OFFSET_7 0x0484 +#define VL53LX_PATCH__OFFSET_7_HI 0x0484 +#define VL53LX_PATCH__OFFSET_7_LO 0x0485 +#define VL53LX_PATCH__OFFSET_8 0x0486 +#define VL53LX_PATCH__OFFSET_8_HI 0x0486 +#define VL53LX_PATCH__OFFSET_8_LO 0x0487 +#define VL53LX_PATCH__OFFSET_9 0x0488 +#define VL53LX_PATCH__OFFSET_9_HI 0x0488 +#define VL53LX_PATCH__OFFSET_9_LO 0x0489 +#define VL53LX_PATCH__OFFSET_10 0x048A +#define VL53LX_PATCH__OFFSET_10_HI 0x048A +#define VL53LX_PATCH__OFFSET_10_LO 0x048B +#define VL53LX_PATCH__OFFSET_11 0x048C +#define VL53LX_PATCH__OFFSET_11_HI 0x048C +#define VL53LX_PATCH__OFFSET_11_LO 0x048D +#define VL53LX_PATCH__OFFSET_12 0x048E +#define VL53LX_PATCH__OFFSET_12_HI 0x048E +#define VL53LX_PATCH__OFFSET_12_LO 0x048F +#define VL53LX_PATCH__OFFSET_13 0x0490 +#define VL53LX_PATCH__OFFSET_13_HI 0x0490 +#define VL53LX_PATCH__OFFSET_13_LO 0x0491 +#define VL53LX_PATCH__OFFSET_14 0x0492 +#define VL53LX_PATCH__OFFSET_14_HI 0x0492 +#define VL53LX_PATCH__OFFSET_14_LO 0x0493 +#define VL53LX_PATCH__OFFSET_15 0x0494 +#define VL53LX_PATCH__OFFSET_15_HI 0x0494 +#define VL53LX_PATCH__OFFSET_15_LO 0x0495 +#define VL53LX_PATCH__ADDRESS_0 0x0496 +#define VL53LX_PATCH__ADDRESS_0_HI 0x0496 +#define VL53LX_PATCH__ADDRESS_0_LO 0x0497 +#define VL53LX_PATCH__ADDRESS_1 0x0498 +#define VL53LX_PATCH__ADDRESS_1_HI 0x0498 +#define VL53LX_PATCH__ADDRESS_1_LO 0x0499 +#define VL53LX_PATCH__ADDRESS_2 0x049A +#define VL53LX_PATCH__ADDRESS_2_HI 0x049A +#define VL53LX_PATCH__ADDRESS_2_LO 0x049B +#define VL53LX_PATCH__ADDRESS_3 0x049C +#define VL53LX_PATCH__ADDRESS_3_HI 0x049C +#define VL53LX_PATCH__ADDRESS_3_LO 0x049D +#define VL53LX_PATCH__ADDRESS_4 0x049E +#define VL53LX_PATCH__ADDRESS_4_HI 0x049E +#define VL53LX_PATCH__ADDRESS_4_LO 0x049F +#define VL53LX_PATCH__ADDRESS_5 0x04A0 +#define VL53LX_PATCH__ADDRESS_5_HI 0x04A0 +#define VL53LX_PATCH__ADDRESS_5_LO 0x04A1 +#define VL53LX_PATCH__ADDRESS_6 0x04A2 +#define VL53LX_PATCH__ADDRESS_6_HI 0x04A2 +#define VL53LX_PATCH__ADDRESS_6_LO 0x04A3 +#define VL53LX_PATCH__ADDRESS_7 0x04A4 +#define VL53LX_PATCH__ADDRESS_7_HI 0x04A4 +#define VL53LX_PATCH__ADDRESS_7_LO 0x04A5 +#define VL53LX_PATCH__ADDRESS_8 0x04A6 +#define VL53LX_PATCH__ADDRESS_8_HI 0x04A6 +#define VL53LX_PATCH__ADDRESS_8_LO 0x04A7 +#define VL53LX_PATCH__ADDRESS_9 0x04A8 +#define VL53LX_PATCH__ADDRESS_9_HI 0x04A8 +#define VL53LX_PATCH__ADDRESS_9_LO 0x04A9 +#define VL53LX_PATCH__ADDRESS_10 0x04AA +#define VL53LX_PATCH__ADDRESS_10_HI 0x04AA +#define VL53LX_PATCH__ADDRESS_10_LO 0x04AB +#define VL53LX_PATCH__ADDRESS_11 0x04AC +#define VL53LX_PATCH__ADDRESS_11_HI 0x04AC +#define VL53LX_PATCH__ADDRESS_11_LO 0x04AD +#define VL53LX_PATCH__ADDRESS_12 0x04AE +#define VL53LX_PATCH__ADDRESS_12_HI 0x04AE +#define VL53LX_PATCH__ADDRESS_12_LO 0x04AF +#define VL53LX_PATCH__ADDRESS_13 0x04B0 +#define VL53LX_PATCH__ADDRESS_13_HI 0x04B0 +#define VL53LX_PATCH__ADDRESS_13_LO 0x04B1 +#define VL53LX_PATCH__ADDRESS_14 0x04B2 +#define VL53LX_PATCH__ADDRESS_14_HI 0x04B2 +#define VL53LX_PATCH__ADDRESS_14_LO 0x04B3 +#define VL53LX_PATCH__ADDRESS_15 0x04B4 +#define VL53LX_PATCH__ADDRESS_15_HI 0x04B4 +#define VL53LX_PATCH__ADDRESS_15_LO 0x04B5 +#define VL53LX_SPI_ASYNC_MUX__CTRL 0x04C0 +#define VL53LX_CLK__CONFIG 0x04C4 +#define VL53LX_GPIO_LV_MUX__CTRL 0x04CC +#define VL53LX_GPIO_LV_PAD__CTRL 0x04CD +#define VL53LX_PAD_I2C_LV__CONFIG 0x04D0 +#define VL53LX_PAD_STARTUP_MODE__VALUE_RO_GO1 0x04D4 +#define VL53LX_HOST_IF__STATUS_GO1 0x04D5 +#define VL53LX_MCU_CLK_GATING__CTRL 0x04D8 +#define VL53LX_TEST__BIST_ROM_CTRL 0x04E0 +#define VL53LX_TEST__BIST_ROM_RESULT 0x04E1 +#define VL53LX_TEST__BIST_ROM_MCU_SIG 0x04E2 +#define VL53LX_TEST__BIST_ROM_MCU_SIG_HI 0x04E2 +#define VL53LX_TEST__BIST_ROM_MCU_SIG_LO 0x04E3 +#define VL53LX_TEST__BIST_RAM_CTRL 0x04E4 +#define VL53LX_TEST__BIST_RAM_RESULT 0x04E5 +#define VL53LX_TEST__TMC 0x04E8 +#define VL53LX_TEST__PLL_BIST_MIN_THRESHOLD 0x04F0 +#define VL53LX_TEST__PLL_BIST_MIN_THRESHOLD_HI 0x04F0 +#define VL53LX_TEST__PLL_BIST_MIN_THRESHOLD_LO 0x04F1 +#define VL53LX_TEST__PLL_BIST_MAX_THRESHOLD 0x04F2 +#define VL53LX_TEST__PLL_BIST_MAX_THRESHOLD_HI 0x04F2 +#define VL53LX_TEST__PLL_BIST_MAX_THRESHOLD_LO 0x04F3 +#define VL53LX_TEST__PLL_BIST_COUNT_OUT 0x04F4 +#define VL53LX_TEST__PLL_BIST_COUNT_OUT_HI 0x04F4 +#define VL53LX_TEST__PLL_BIST_COUNT_OUT_LO 0x04F5 +#define VL53LX_TEST__PLL_BIST_GONOGO 0x04F6 +#define VL53LX_TEST__PLL_BIST_CTRL 0x04F7 +#define VL53LX_RANGING_CORE__DEVICE_ID 0x0680 +#define VL53LX_RANGING_CORE__REVISION_ID 0x0681 +#define VL53LX_RANGING_CORE__CLK_CTRL1 0x0683 +#define VL53LX_RANGING_CORE__CLK_CTRL2 0x0684 +#define VL53LX_RANGING_CORE__WOI_1 0x0685 +#define VL53LX_RANGING_CORE__WOI_REF_1 0x0686 +#define VL53LX_RANGING_CORE__START_RANGING 0x0687 +#define VL53LX_RANGING_CORE__LOW_LIMIT_1 0x0690 +#define VL53LX_RANGING_CORE__HIGH_LIMIT_1 0x0691 +#define VL53LX_RANGING_CORE__LOW_LIMIT_REF_1 0x0692 +#define VL53LX_RANGING_CORE__HIGH_LIMIT_REF_1 0x0693 +#define VL53LX_RANGING_CORE__QUANTIFIER_1_MSB 0x0694 +#define VL53LX_RANGING_CORE__QUANTIFIER_1_LSB 0x0695 +#define VL53LX_RANGING_CORE__QUANTIFIER_REF_1_MSB 0x0696 +#define VL53LX_RANGING_CORE__QUANTIFIER_REF_1_LSB 0x0697 +#define VL53LX_RANGING_CORE__AMBIENT_OFFSET_1_MSB 0x0698 +#define VL53LX_RANGING_CORE__AMBIENT_OFFSET_1_LSB 0x0699 +#define VL53LX_RANGING_CORE__AMBIENT_OFFSET_REF_1_MSB 0x069A +#define VL53LX_RANGING_CORE__AMBIENT_OFFSET_REF_1_LSB 0x069B +#define VL53LX_RANGING_CORE__FILTER_STRENGTH_1 0x069C +#define VL53LX_RANGING_CORE__FILTER_STRENGTH_REF_1 0x069D +#define VL53LX_RANGING_CORE__SIGNAL_EVENT_LIMIT_1_MSB 0x069E +#define VL53LX_RANGING_CORE__SIGNAL_EVENT_LIMIT_1_LSB 0x069F +#define VL53LX_RANGING_CORE__SIGNAL_EVENT_LIMIT_REF_1_MSB 0x06A0 +#define VL53LX_RANGING_CORE__SIGNAL_EVENT_LIMIT_REF_1_LSB 0x06A1 +#define VL53LX_RANGING_CORE__TIMEOUT_OVERALL_PERIODS_MSB 0x06A4 +#define VL53LX_RANGING_CORE__TIMEOUT_OVERALL_PERIODS_LSB 0x06A5 +#define VL53LX_RANGING_CORE__INVERT_HW 0x06A6 +#define VL53LX_RANGING_CORE__FORCE_HW 0x06A7 +#define VL53LX_RANGING_CORE__STATIC_HW_VALUE 0x06A8 +#define VL53LX_RANGING_CORE__FORCE_CONTINUOUS_AMBIENT 0x06A9 +#define VL53LX_RANGING_CORE__TEST_PHASE_SELECT_TO_FILTER 0x06AA +#define VL53LX_RANGING_CORE__TEST_PHASE_SELECT_TO_TIMING_GEN 0x06AB +#define VL53LX_RANGING_CORE__INITIAL_PHASE_VALUE_1 0x06AC +#define VL53LX_RANGING_CORE__INITIAL_PHASE_VALUE_REF_1 0x06AD +#define VL53LX_RANGING_CORE__FORCE_UP_IN 0x06AE +#define VL53LX_RANGING_CORE__FORCE_DN_IN 0x06AF +#define VL53LX_RANGING_CORE__STATIC_UP_VALUE_1 0x06B0 +#define VL53LX_RANGING_CORE__STATIC_UP_VALUE_REF_1 0x06B1 +#define VL53LX_RANGING_CORE__STATIC_DN_VALUE_1 0x06B2 +#define VL53LX_RANGING_CORE__STATIC_DN_VALUE_REF_1 0x06B3 +#define VL53LX_RANGING_CORE__MONITOR_UP_DN 0x06B4 +#define VL53LX_RANGING_CORE__INVERT_UP_DN 0x06B5 +#define VL53LX_RANGING_CORE__CPUMP_1 0x06B6 +#define VL53LX_RANGING_CORE__CPUMP_2 0x06B7 +#define VL53LX_RANGING_CORE__CPUMP_3 0x06B8 +#define VL53LX_RANGING_CORE__OSC_1 0x06B9 +#define VL53LX_RANGING_CORE__PLL_1 0x06BB +#define VL53LX_RANGING_CORE__PLL_2 0x06BC +#define VL53LX_RANGING_CORE__REFERENCE_1 0x06BD +#define VL53LX_RANGING_CORE__REFERENCE_3 0x06BF +#define VL53LX_RANGING_CORE__REFERENCE_4 0x06C0 +#define VL53LX_RANGING_CORE__REFERENCE_5 0x06C1 +#define VL53LX_RANGING_CORE__REGAVDD1V2 0x06C3 +#define VL53LX_RANGING_CORE__CALIB_1 0x06C4 +#define VL53LX_RANGING_CORE__CALIB_2 0x06C5 +#define VL53LX_RANGING_CORE__CALIB_3 0x06C6 +#define VL53LX_RANGING_CORE__TST_MUX_SEL1 0x06C9 +#define VL53LX_RANGING_CORE__TST_MUX_SEL2 0x06CA +#define VL53LX_RANGING_CORE__TST_MUX 0x06CB +#define VL53LX_RANGING_CORE__GPIO_OUT_TESTMUX 0x06CC +#define VL53LX_RANGING_CORE__CUSTOM_FE 0x06CD +#define VL53LX_RANGING_CORE__CUSTOM_FE_2 0x06CE +#define VL53LX_RANGING_CORE__SPAD_READOUT 0x06CF +#define VL53LX_RANGING_CORE__SPAD_READOUT_1 0x06D0 +#define VL53LX_RANGING_CORE__SPAD_READOUT_2 0x06D1 +#define VL53LX_RANGING_CORE__SPAD_PS 0x06D2 +#define VL53LX_RANGING_CORE__LASER_SAFETY_2 0x06D4 +#define VL53LX_RANGING_CORE__NVM_CTRL__MODE 0x0780 +#define VL53LX_RANGING_CORE__NVM_CTRL__PDN 0x0781 +#define VL53LX_RANGING_CORE__NVM_CTRL__PROGN 0x0782 +#define VL53LX_RANGING_CORE__NVM_CTRL__READN 0x0783 +#define VL53LX_RANGING_CORE__NVM_CTRL__PULSE_WIDTH_MSB 0x0784 +#define VL53LX_RANGING_CORE__NVM_CTRL__PULSE_WIDTH_LSB 0x0785 +#define VL53LX_RANGING_CORE__NVM_CTRL__HV_RISE_MSB 0x0786 +#define VL53LX_RANGING_CORE__NVM_CTRL__HV_RISE_LSB 0x0787 +#define VL53LX_RANGING_CORE__NVM_CTRL__HV_FALL_MSB 0x0788 +#define VL53LX_RANGING_CORE__NVM_CTRL__HV_FALL_LSB 0x0789 +#define VL53LX_RANGING_CORE__NVM_CTRL__TST 0x078A +#define VL53LX_RANGING_CORE__NVM_CTRL__TESTREAD 0x078B +#define VL53LX_RANGING_CORE__NVM_CTRL__DATAIN_MMM 0x078C +#define VL53LX_RANGING_CORE__NVM_CTRL__DATAIN_LMM 0x078D +#define VL53LX_RANGING_CORE__NVM_CTRL__DATAIN_LLM 0x078E +#define VL53LX_RANGING_CORE__NVM_CTRL__DATAIN_LLL 0x078F +#define VL53LX_RANGING_CORE__NVM_CTRL__DATAOUT_MMM 0x0790 +#define VL53LX_RANGING_CORE__NVM_CTRL__DATAOUT_LMM 0x0791 +#define VL53LX_RANGING_CORE__NVM_CTRL__DATAOUT_LLM 0x0792 +#define VL53LX_RANGING_CORE__NVM_CTRL__DATAOUT_LLL 0x0793 +#define VL53LX_RANGING_CORE__NVM_CTRL__ADDR 0x0794 +#define VL53LX_RANGING_CORE__NVM_CTRL__DATAOUT_ECC 0x0795 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_0 0x0796 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_1 0x0797 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_2 0x0798 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_3 0x0799 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_4 0x079A +#define VL53LX_RANGING_CORE__RET_SPAD_EN_5 0x079B +#define VL53LX_RANGING_CORE__RET_SPAD_EN_6 0x079C +#define VL53LX_RANGING_CORE__RET_SPAD_EN_7 0x079D +#define VL53LX_RANGING_CORE__RET_SPAD_EN_8 0x079E +#define VL53LX_RANGING_CORE__RET_SPAD_EN_9 0x079F +#define VL53LX_RANGING_CORE__RET_SPAD_EN_10 0x07A0 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_11 0x07A1 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_12 0x07A2 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_13 0x07A3 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_14 0x07A4 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_15 0x07A5 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_16 0x07A6 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_17 0x07A7 +#define VL53LX_RANGING_CORE__SPAD_SHIFT_EN 0x07BA +#define VL53LX_RANGING_CORE__SPAD_DISABLE_CTRL 0x07BB +#define VL53LX_RANGING_CORE__SPAD_EN_SHIFT_OUT_DEBUG 0x07BC +#define VL53LX_RANGING_CORE__SPI_MODE 0x07BD +#define VL53LX_RANGING_CORE__GPIO_DIR 0x07BE +#define VL53LX_RANGING_CORE__VCSEL_PERIOD 0x0880 +#define VL53LX_RANGING_CORE__VCSEL_START 0x0881 +#define VL53LX_RANGING_CORE__VCSEL_STOP 0x0882 +#define VL53LX_RANGING_CORE__VCSEL_1 0x0885 +#define VL53LX_RANGING_CORE__VCSEL_STATUS 0x088D +#define VL53LX_RANGING_CORE__STATUS 0x0980 +#define VL53LX_RANGING_CORE__LASER_CONTINUITY_STATE 0x0981 +#define VL53LX_RANGING_CORE__RANGE_1_MMM 0x0982 +#define VL53LX_RANGING_CORE__RANGE_1_LMM 0x0983 +#define VL53LX_RANGING_CORE__RANGE_1_LLM 0x0984 +#define VL53LX_RANGING_CORE__RANGE_1_LLL 0x0985 +#define VL53LX_RANGING_CORE__RANGE_REF_1_MMM 0x0986 +#define VL53LX_RANGING_CORE__RANGE_REF_1_LMM 0x0987 +#define VL53LX_RANGING_CORE__RANGE_REF_1_LLM 0x0988 +#define VL53LX_RANGING_CORE__RANGE_REF_1_LLL 0x0989 +#define VL53LX_RANGING_CORE__AMBIENT_WINDOW_EVENTS_1_MMM 0x098A +#define VL53LX_RANGING_CORE__AMBIENT_WINDOW_EVENTS_1_LMM 0x098B +#define VL53LX_RANGING_CORE__AMBIENT_WINDOW_EVENTS_1_LLM 0x098C +#define VL53LX_RANGING_CORE__AMBIENT_WINDOW_EVENTS_1_LLL 0x098D +#define VL53LX_RANGING_CORE__RANGING_TOTAL_EVENTS_1_MMM 0x098E +#define VL53LX_RANGING_CORE__RANGING_TOTAL_EVENTS_1_LMM 0x098F +#define VL53LX_RANGING_CORE__RANGING_TOTAL_EVENTS_1_LLM 0x0990 +#define VL53LX_RANGING_CORE__RANGING_TOTAL_EVENTS_1_LLL 0x0991 +#define VL53LX_RANGING_CORE__SIGNAL_TOTAL_EVENTS_1_MMM 0x0992 +#define VL53LX_RANGING_CORE__SIGNAL_TOTAL_EVENTS_1_LMM 0x0993 +#define VL53LX_RANGING_CORE__SIGNAL_TOTAL_EVENTS_1_LLM 0x0994 +#define VL53LX_RANGING_CORE__SIGNAL_TOTAL_EVENTS_1_LLL 0x0995 +#define VL53LX_RANGING_CORE__TOTAL_PERIODS_ELAPSED_1_MM 0x0996 +#define VL53LX_RANGING_CORE__TOTAL_PERIODS_ELAPSED_1_LM 0x0997 +#define VL53LX_RANGING_CORE__TOTAL_PERIODS_ELAPSED_1_LL 0x0998 +#define VL53LX_RANGING_CORE__AMBIENT_MISMATCH_MM 0x0999 +#define VL53LX_RANGING_CORE__AMBIENT_MISMATCH_LM 0x099A +#define VL53LX_RANGING_CORE__AMBIENT_MISMATCH_LL 0x099B +#define VL53LX_RANGING_CORE__AMBIENT_WINDOW_EVENTS_REF_1_MMM 0x099C +#define VL53LX_RANGING_CORE__AMBIENT_WINDOW_EVENTS_REF_1_LMM 0x099D +#define VL53LX_RANGING_CORE__AMBIENT_WINDOW_EVENTS_REF_1_LLM 0x099E +#define VL53LX_RANGING_CORE__AMBIENT_WINDOW_EVENTS_REF_1_LLL 0x099F +#define VL53LX_RANGING_CORE__RANGING_TOTAL_EVENTS_REF_1_MMM 0x09A0 +#define VL53LX_RANGING_CORE__RANGING_TOTAL_EVENTS_REF_1_LMM 0x09A1 +#define VL53LX_RANGING_CORE__RANGING_TOTAL_EVENTS_REF_1_LLM 0x09A2 +#define VL53LX_RANGING_CORE__RANGING_TOTAL_EVENTS_REF_1_LLL 0x09A3 +#define VL53LX_RANGING_CORE__SIGNAL_TOTAL_EVENTS_REF_1_MMM 0x09A4 +#define VL53LX_RANGING_CORE__SIGNAL_TOTAL_EVENTS_REF_1_LMM 0x09A5 +#define VL53LX_RANGING_CORE__SIGNAL_TOTAL_EVENTS_REF_1_LLM 0x09A6 +#define VL53LX_RANGING_CORE__SIGNAL_TOTAL_EVENTS_REF_1_LLL 0x09A7 +#define VL53LX_RANGING_CORE__TOTAL_PERIODS_ELAPSED_REF_1_MM 0x09A8 +#define VL53LX_RANGING_CORE__TOTAL_PERIODS_ELAPSED_REF_1_LM 0x09A9 +#define VL53LX_RANGING_CORE__TOTAL_PERIODS_ELAPSED_REF_1_LL 0x09AA +#define VL53LX_RANGING_CORE__AMBIENT_MISMATCH_REF_MM 0x09AB +#define VL53LX_RANGING_CORE__AMBIENT_MISMATCH_REF_LM 0x09AC +#define VL53LX_RANGING_CORE__AMBIENT_MISMATCH_REF_LL 0x09AD +#define VL53LX_RANGING_CORE__GPIO_CONFIG__A0 0x0A00 +#define VL53LX_RANGING_CORE__RESET_CONTROL__A0 0x0A01 +#define VL53LX_RANGING_CORE__INTR_MANAGER__A0 0x0A02 +#define VL53LX_RANGING_CORE__POWER_FSM_TIME_OSC__A0 0x0A06 +#define VL53LX_RANGING_CORE__VCSEL_ATEST__A0 0x0A07 +#define VL53LX_RANGING_CORE__VCSEL_PERIOD_CLIPPED__A0 0x0A08 +#define VL53LX_RANGING_CORE__VCSEL_STOP_CLIPPED__A0 0x0A09 +#define VL53LX_RANGING_CORE__CALIB_2__A0 0x0A0A +#define VL53LX_RANGING_CORE__STOP_CONDITION__A0 0x0A0B +#define VL53LX_RANGING_CORE__STATUS_RESET__A0 0x0A0C +#define VL53LX_RANGING_CORE__READOUT_CFG__A0 0x0A0D +#define VL53LX_RANGING_CORE__WINDOW_SETTING__A0 0x0A0E +#define VL53LX_RANGING_CORE__VCSEL_DELAY__A0 0x0A1A +#define VL53LX_RANGING_CORE__REFERENCE_2__A0 0x0A1B +#define VL53LX_RANGING_CORE__REGAVDD1V2__A0 0x0A1D +#define VL53LX_RANGING_CORE__TST_MUX__A0 0x0A1F +#define VL53LX_RANGING_CORE__CUSTOM_FE_2__A0 0x0A20 +#define VL53LX_RANGING_CORE__SPAD_READOUT__A0 0x0A21 +#define VL53LX_RANGING_CORE__CPUMP_1__A0 0x0A22 +#define VL53LX_RANGING_CORE__SPARE_REGISTER__A0 0x0A23 +#define VL53LX_RANGING_CORE__VCSEL_CONT_STAGE5_BYPASS__A0 0x0A24 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_18 0x0A25 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_19 0x0A26 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_20 0x0A27 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_21 0x0A28 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_22 0x0A29 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_23 0x0A2A +#define VL53LX_RANGING_CORE__RET_SPAD_EN_24 0x0A2B +#define VL53LX_RANGING_CORE__RET_SPAD_EN_25 0x0A2C +#define VL53LX_RANGING_CORE__RET_SPAD_EN_26 0x0A2D +#define VL53LX_RANGING_CORE__RET_SPAD_EN_27 0x0A2E +#define VL53LX_RANGING_CORE__RET_SPAD_EN_28 0x0A2F +#define VL53LX_RANGING_CORE__RET_SPAD_EN_29 0x0A30 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_30 0x0A31 +#define VL53LX_RANGING_CORE__RET_SPAD_EN_31 0x0A32 +#define VL53LX_RANGING_CORE__REF_SPAD_EN_0__EWOK 0x0A33 +#define VL53LX_RANGING_CORE__REF_SPAD_EN_1__EWOK 0x0A34 +#define VL53LX_RANGING_CORE__REF_SPAD_EN_2__EWOK 0x0A35 +#define VL53LX_RANGING_CORE__REF_SPAD_EN_3__EWOK 0x0A36 +#define VL53LX_RANGING_CORE__REF_SPAD_EN_4__EWOK 0x0A37 +#define VL53LX_RANGING_CORE__REF_SPAD_EN_5__EWOK 0x0A38 +#define VL53LX_RANGING_CORE__REF_EN_START_SELECT 0x0A39 +#define VL53LX_RANGING_CORE__REGDVDD1V2_ATEST__EWOK 0x0A41 +#define VL53LX_PRIVATE__PATCH_BASE_ADDR_RSLV 0x0E00 +#define VL53LX_PREV_SHADOW_RESULT__INTERRUPT_STATUS 0x0ED0 +#define VL53LX_PREV_SHADOW_RESULT__RANGE_STATUS 0x0ED1 +#define VL53LX_PREV_SHADOW_RESULT__REPORT_STATUS 0x0ED2 +#define VL53LX_PREV_SHADOW_RESULT__STREAM_COUNT 0x0ED3 +#define VL53LX_PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0 0x0ED4 +#define VL53LX_PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_HI 0x0ED4 +#define VL53LX_PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_LO 0x0ED5 +#define VL53LX_PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0 0x0ED6 +#define VL53LX_PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_HI 0x0E= D6 +#define VL53LX_PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_LO 0x0E= D7 +#define VL53LX_PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0 0x0ED8 +#define VL53LX_PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_HI 0x0ED8 +#define VL53LX_PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_LO 0x0ED9 +#define VL53LX_PREV_SHADOW_RESULT__SIGMA_SD0 0x0EDA +#define VL53LX_PREV_SHADOW_RESULT__SIGMA_SD0_HI 0x0EDA +#define VL53LX_PREV_SHADOW_RESULT__SIGMA_SD0_LO 0x0EDB +#define VL53LX_PREV_SHADOW_RESULT__PHASE_SD0 0x0EDC +#define VL53LX_PREV_SHADOW_RESULT__PHASE_SD0_HI 0x0EDC +#define VL53LX_PREV_SHADOW_RESULT__PHASE_SD0_LO 0x0EDD +#define VL53LX_PREV_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 = 0x0EDE +#define VL53LX_PREV__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_HI 0x0EDE +#define VL53LX_PREV__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_LO 0x0EDF +#define VL53LX_PREV__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 0= x0EE0 +#define VL53LX_PPEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_HI 0x0= EE0 +#define VL53LX_PPEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_LO 0x0= EE1 +#define VL53LX_PREV_SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0 0x0= EE2 +#define VL53LX_PREV_SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x0EE2 +#define VL53LX_PREV_SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x0EE3 +#define VL53LX_PREV_SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0 0x0= EE4 +#define VL53LX_PREV_SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_HI = 0x0EE4 +#define VL53LX_PREV_SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_LO = 0x0EE5 +#define VL53LX_PREV_SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0 0x0EE6 +#define VL53LX_PREV_SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_HI 0x0EE6 +#define VL53LX_PREV_SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_LO 0x0EE7 +#define VL53LX_PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1 0x0EE8 +#define VL53LX_PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_HI 0x0EE8 +#define VL53LX_PREV_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_LO 0x0EE9 +#define VL53LX_PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1 0x0EEA +#define VL53LX_PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_HI 0x0E= EA +#define VL53LX_PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_LO 0x0E= EB +#define VL53LX_PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1 0x0EEC +#define VL53LX_PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_HI 0x0EEC +#define VL53LX_PREV_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_LO 0x0EED +#define VL53LX_PREV_SHADOW_RESULT__SIGMA_SD1 0x0EEE +#define VL53LX_PREV_SHADOW_RESULT__SIGMA_SD1_HI 0x0EEE +#define VL53LX_PREV_SHADOW_RESULT__SIGMA_SD1_LO 0x0EEF +#define VL53LX_PREV_SHADOW_RESULT__PHASE_SD1 0x0EF0 +#define VL53LX_PREV_SHADOW_RESULT__PHASE_SD1_HI 0x0EF0 +#define VL53LX_PREV_SHADOW_RESULT__PHASE_SD1_LO 0x0EF1 +#define VL53LX_PREV_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1 = 0x0EF2 +#define VL53LX_PFINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_HI 0x0EF2 +#define VL53LX_PFINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_LO 0x0EF3 +#define VL53LX_PREV_SHADOW_RESULT__SPARE_0_SD1 0x0EF4 +#define VL53LX_PREV_SHADOW_RESULT__SPARE_0_SD1_HI 0x0EF4 +#define VL53LX_PREV_SHADOW_RESULT__SPARE_0_SD1_LO 0x0EF5 +#define VL53LX_PREV_SHADOW_RESULT__SPARE_1_SD1 0x0EF6 +#define VL53LX_PREV_SHADOW_RESULT__SPARE_1_SD1_HI 0x0EF6 +#define VL53LX_PREV_SHADOW_RESULT__SPARE_1_SD1_LO 0x0EF7 +#define VL53LX_PREV_SHADOW_RESULT__SPARE_2_SD1 0x0EF8 +#define VL53LX_PREV_SHADOW_RESULT__SPARE_2_SD1_HI 0x0EF8 +#define VL53LX_PREV_SHADOW_RESULT__SPARE_2_SD1_LO 0x0EF9 +#define VL53LX_PREV_SHADOW_RESULT__SPARE_3_SD1 0x0EFA +#define VL53LX_PREV_SHADOW_RESULT__SPARE_3_SD1_HI 0x0EFA +#define VL53LX_PREV_SHADOW_RESULT__SPARE_3_SD1_LO 0x0EFB +#define VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0 0x0EFC +#define VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_3 0x0EFC +#define VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_2 0x0EFD +#define VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_1 0x0EFE +#define VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_0 0x0EFF +#define VL53LX_PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0 0x0F00 +#define VL53LX_PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_3 0x0F00 +#define VL53LX_PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_2 0x0F01 +#define VL53LX_PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_1 0x0F02 +#define VL53LX_PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_0 0x0F03 +#define VL53LX_PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0 0x0F04 +#define VL53LX_PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_3 0x0F04 +#define VL53LX_PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_2 0x0F05 +#define VL53LX_PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_1 0x0F06 +#define VL53LX_PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_0 0x0F07 +#define VL53LX_PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0 0x0F08 +#define VL53LX_PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_3 0x0F08 +#define VL53LX_PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_2 0x0F09 +#define VL53LX_PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_1 0x0F0A +#define VL53LX_PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_0 0x0F0B +#define VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1 0x0F0C +#define VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_3 0x0F0C +#define VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_2 0x0F0D +#define VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_1 0x0F0E +#define VL53LX_PREV_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_0 0x0F0F +#define VL53LX_PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1 0x0F10 +#define VL53LX_PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_3 0x0F10 +#define VL53LX_PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_2 0x0F11 +#define VL53LX_PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_1 0x0F12 +#define VL53LX_PREV_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_0 0x0F13 +#define VL53LX_PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1 0x0F14 +#define VL53LX_PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_3 0x0F14 +#define VL53LX_PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_2 0x0F15 +#define VL53LX_PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_1 0x0F16 +#define VL53LX_PREV_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_0 0x0F17 +#define VL53LX_PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1 0x0F18 +#define VL53LX_PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_3 0x0F18 +#define VL53LX_PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_2 0x0F19 +#define VL53LX_PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_1 0x0F1A +#define VL53LX_PREV_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_0 0x0F1B +#define VL53LX_PREV_SHADOW_RESULT_CORE__SPARE_0 0x0F1C +#define VL53LX_RESULT__DEBUG_STATUS 0x0F20 +#define VL53LX_RESULT__DEBUG_STAGE 0x0F21 +#define VL53LX_GPH__SYSTEM__THRESH_RATE_HIGH 0x0F24 +#define VL53LX_GPH__SYSTEM__THRESH_RATE_HIGH_HI 0x0F24 +#define VL53LX_GPH__SYSTEM__THRESH_RATE_HIGH_LO 0x0F25 +#define VL53LX_GPH__SYSTEM__THRESH_RATE_LOW 0x0F26 +#define VL53LX_GPH__SYSTEM__THRESH_RATE_LOW_HI 0x0F26 +#define VL53LX_GPH__SYSTEM__THRESH_RATE_LOW_LO 0x0F27 +#define VL53LX_GPH__SYSTEM__INTERRUPT_CONFIG_GPIO 0x0F28 +#define VL53LX_GPH__DSS_CONFIG__ROI_MODE_CONTROL 0x0F2F +#define VL53LX_GPH__DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT 0x0F30 +#define VL53LX_GPH__DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT_HI 0x0F30 +#define VL53LX_GPH__DSS_CONFIG__MANUAL_EFFECTIVE_SPADS_SELECT_LO 0x0F31 +#define VL53LX_GPH__DSS_CONFIG__MANUAL_BLOCK_SELECT 0x0F32 +#define VL53LX_GPH__DSS_CONFIG__MAX_SPADS_LIMIT 0x0F33 +#define VL53LX_GPH__DSS_CONFIG__MIN_SPADS_LIMIT 0x0F34 +#define VL53LX_GPH__MM_CONFIG__TIMEOUT_MACROP_A_HI 0x0F36 +#define VL53LX_GPH__MM_CONFIG__TIMEOUT_MACROP_A_LO 0x0F37 +#define VL53LX_GPH__MM_CONFIG__TIMEOUT_MACROP_B_HI 0x0F38 +#define VL53LX_GPH__MM_CONFIG__TIMEOUT_MACROP_B_LO 0x0F39 +#define VL53LX_GPH__RANGE_CONFIG__TIMEOUT_MACROP_A_HI 0x0F3A +#define VL53LX_GPH__RANGE_CONFIG__TIMEOUT_MACROP_A_LO 0x0F3B +#define VL53LX_GPH__RANGE_CONFIG__VCSEL_PERIOD_A 0x0F3C +#define VL53LX_GPH__RANGE_CONFIG__VCSEL_PERIOD_B 0x0F3D +#define VL53LX_GPH__RANGE_CONFIG__TIMEOUT_MACROP_B_HI 0x0F3E +#define VL53LX_GPH__RANGE_CONFIG__TIMEOUT_MACROP_B_LO 0x0F3F +#define VL53LX_GPH__RANGE_CONFIG__SIGMA_THRESH 0x0F40 +#define VL53LX_GPH__RANGE_CONFIG__SIGMA_THRESH_HI 0x0F40 +#define VL53LX_GPH__RANGE_CONFIG__SIGMA_THRESH_LO 0x0F41 +#define VL53LX_GPH__RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS 0x0F42 +#define VL53LX_GPH__RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS_HI 0x0F42 +#define VL53LX_GPH__RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS_LO 0x0F43 +#define VL53LX_GPH__RANGE_CONFIG__VALID_PHASE_LOW 0x0F44 +#define VL53LX_GPH__RANGE_CONFIG__VALID_PHASE_HIGH 0x0F45 +#define VL53LX_FIRMWARE__INTERNAL_STREAM_COUNT_DIV 0x0F46 +#define VL53LX_FIRMWARE__INTERNAL_STREAM_COUNTER_VAL 0x0F47 +#define VL53LX_DSS_CALC__ROI_CTRL 0x0F54 +#define VL53LX_DSS_CALC__SPARE_1 0x0F55 +#define VL53LX_DSS_CALC__SPARE_2 0x0F56 +#define VL53LX_DSS_CALC__SPARE_3 0x0F57 +#define VL53LX_DSS_CALC__SPARE_4 0x0F58 +#define VL53LX_DSS_CALC__SPARE_5 0x0F59 +#define VL53LX_DSS_CALC__SPARE_6 0x0F5A +#define VL53LX_DSS_CALC__SPARE_7 0x0F5B +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_0 0x0F5C +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_1 0x0F5D +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_2 0x0F5E +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_3 0x0F5F +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_4 0x0F60 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_5 0x0F61 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_6 0x0F62 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_7 0x0F63 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_8 0x0F64 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_9 0x0F65 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_10 0x0F66 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_11 0x0F67 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_12 0x0F68 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_13 0x0F69 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_14 0x0F6A +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_15 0x0F6B +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_16 0x0F6C +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_17 0x0F6D +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_18 0x0F6E +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_19 0x0F6F +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_20 0x0F70 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_21 0x0F71 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_22 0x0F72 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_23 0x0F73 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_24 0x0F74 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_25 0x0F75 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_26 0x0F76 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_27 0x0F77 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_28 0x0F78 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_29 0x0F79 +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_30 0x0F7A +#define VL53LX_DSS_CALC__USER_ROI_SPAD_EN_31 0x0F7B +#define VL53LX_DSS_CALC__USER_ROI_0 0x0F7C +#define VL53LX_DSS_CALC__USER_ROI_1 0x0F7D +#define VL53LX_DSS_CALC__MODE_ROI_0 0x0F7E +#define VL53LX_DSS_CALC__MODE_ROI_1 0x0F7F +#define VL53LX_SIGMA_ESTIMATOR_CALC__SPARE_0 0x0F80 +#define VL53LX_VHV_RESULT__PEAK_SIGNAL_RATE_MCPS 0x0F82 +#define VL53LX_VHV_RESULT__PEAK_SIGNAL_RATE_MCPS_HI 0x0F82 +#define VL53LX_VHV_RESULT__PEAK_SIGNAL_RATE_MCPS_LO 0x0F83 +#define VL53LX_VHV_RESULT__SIGNAL_TOTAL_EVENTS_REF 0x0F84 +#define VL53LX_VHV_RESULT__SIGNAL_TOTAL_EVENTS_REF_3 0x0F84 +#define VL53LX_VHV_RESULT__SIGNAL_TOTAL_EVENTS_REF_2 0x0F85 +#define VL53LX_VHV_RESULT__SIGNAL_TOTAL_EVENTS_REF_1 0x0F86 +#define VL53LX_VHV_RESULT__SIGNAL_TOTAL_EVENTS_REF_0 0x0F87 +#define VL53LX_PHASECAL_RESULT__PHASE_OUTPUT_REF 0x0F88 +#define VL53LX_PHASECAL_RESULT__PHASE_OUTPUT_REF_HI 0x0F88 +#define VL53LX_PHASECAL_RESULT__PHASE_OUTPUT_REF_LO 0x0F89 +#define VL53LX_DSS_RESULT__TOTAL_RATE_PER_SPAD 0x0F8A +#define VL53LX_DSS_RESULT__TOTAL_RATE_PER_SPAD_HI 0x0F8A +#define VL53LX_DSS_RESULT__TOTAL_RATE_PER_SPAD_LO 0x0F8B +#define VL53LX_DSS_RESULT__ENABLED_BLOCKS 0x0F8C +#define VL53LX_DSS_RESULT__NUM_REQUESTED_SPADS 0x0F8E +#define VL53LX_DSS_RESULT__NUM_REQUESTED_SPADS_HI 0x0F8E +#define VL53LX_DSS_RESULT__NUM_REQUESTED_SPADS_LO 0x0F8F +#define VL53LX_MM_RESULT__INNER_INTERSECTION_RATE 0x0F92 +#define VL53LX_MM_RESULT__INNER_INTERSECTION_RATE_HI 0x0F92 +#define VL53LX_MM_RESULT__INNER_INTERSECTION_RATE_LO 0x0F93 +#define VL53LX_MM_RESULT__OUTER_COMPLEMENT_RATE 0x0F94 +#define VL53LX_MM_RESULT__OUTER_COMPLEMENT_RATE_HI 0x0F94 +#define VL53LX_MM_RESULT__OUTER_COMPLEMENT_RATE_LO 0x0F95 +#define VL53LX_MM_RESULT__TOTAL_OFFSET 0x0F96 +#define VL53LX_MM_RESULT__TOTAL_OFFSET_HI 0x0F96 +#define VL53LX_MM_RESULT__TOTAL_OFFSET_LO 0x0F97 +#define VL53LX_XTALK_CALC__XTALK_FOR_ENABLED_SPADS 0x0F98 +#define VL53LX_XTALK_CALC__XTALK_FOR_ENABLED_SPADS_3 0x0F98 +#define VL53LX_XTALK_CALC__XTALK_FOR_ENABLED_SPADS_2 0x0F99 +#define VL53LX_XTALK_CALC__XTALK_FOR_ENABLED_SPADS_1 0x0F9A +#define VL53LX_XTALK_CALC__XTALK_FOR_ENABLED_SPADS_0 0x0F9B +#define VL53LX_XTALK_RESULT__AVG_XTALK_USER_ROI_KCPS 0x0F9C +#define VL53LX_XTALK_RESULT__AVG_XTALK_USER_ROI_KCPS_3 0x0F9C +#define VL53LX_XTALK_RESULT__AVG_XTALK_USER_ROI_KCPS_2 0x0F9D +#define VL53LX_XTALK_RESULT__AVG_XTALK_USER_ROI_KCPS_1 0x0F9E +#define VL53LX_XTALK_RESULT__AVG_XTALK_USER_ROI_KCPS_0 0x0F9F +#define VL53LX_XTALK_RESULT__AVG_XTALK_MM_INNER_ROI_KCPS 0x0FA0 +#define VL53LX_XTALK_RESULT__AVG_XTALK_MM_INNER_ROI_KCPS_3 0x0FA0 +#define VL53LX_XTALK_RESULT__AVG_XTALK_MM_INNER_ROI_KCPS_2 0x0FA1 +#define VL53LX_XTALK_RESULT__AVG_XTALK_MM_INNER_ROI_KCPS_1 0x0FA2 +#define VL53LX_XTALK_RESULT__AVG_XTALK_MM_INNER_ROI_KCPS_0 0x0FA3 +#define VL53LX_XTALK_RESULT__AVG_XTALK_MM_OUTER_ROI_KCPS 0x0FA4 +#define VL53LX_XTALK_RESULT__AVG_XTALK_MM_OUTER_ROI_KCPS_3 0x0FA4 +#define VL53LX_XTALK_RESULT__AVG_XTALK_MM_OUTER_ROI_KCPS_2 0x0FA5 +#define VL53LX_XTALK_RESULT__AVG_XTALK_MM_OUTER_ROI_KCPS_1 0x0FA6 +#define VL53LX_XTALK_RESULT__AVG_XTALK_MM_OUTER_ROI_KCPS_0 0x0FA7 +#define VL53LX_RANGE_RESULT__ACCUM_PHASE 0x0FA8 +#define VL53LX_RANGE_RESULT__ACCUM_PHASE_3 0x0FA8 +#define VL53LX_RANGE_RESULT__ACCUM_PHASE_2 0x0FA9 +#define VL53LX_RANGE_RESULT__ACCUM_PHASE_1 0x0FAA +#define VL53LX_RANGE_RESULT__ACCUM_PHASE_0 0x0FAB +#define VL53LX_RANGE_RESULT__OFFSET_CORRECTED_RANGE 0x0FAC +#define VL53LX_RANGE_RESULT__OFFSET_CORRECTED_RANGE_HI 0x0FAC +#define VL53LX_RANGE_RESULT__OFFSET_CORRECTED_RANGE_LO 0x0FAD +#define VL53LX_SHADOW_PHASECAL_RESULT__VCSEL_START 0x0FAE +#define VL53LX_SHADOW_RESULT__INTERRUPT_STATUS 0x0FB0 +#define VL53LX_SHADOW_RESULT__RANGE_STATUS 0x0FB1 +#define VL53LX_SHADOW_RESULT__REPORT_STATUS 0x0FB2 +#define VL53LX_SHADOW_RESULT__STREAM_COUNT 0x0FB3 +#define VL53LX_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0 0x0FB4 +#define VL53LX_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_HI 0x0FB4 +#define VL53LX_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0_LO 0x0FB5 +#define VL53LX_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0 0x0FB6 +#define VL53LX_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_HI 0x0FB6 +#define VL53LX_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_LO 0x0FB7 +#define VL53LX_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0 0x0FB8 +#define VL53LX_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_HI 0x0FB8 +#define VL53LX_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD0_LO 0x0FB9 +#define VL53LX_SHADOW_RESULT__SIGMA_SD0 0x0FBA +#define VL53LX_SHADOW_RESULT__SIGMA_SD0_HI 0x0FBA +#define VL53LX_SHADOW_RESULT__SIGMA_SD0_LO 0x0FBB +#define VL53LX_SHADOW_RESULT__PHASE_SD0 0x0FBC +#define VL53LX_SHADOW_RESULT__PHASE_SD0_HI 0x0FBC +#define VL53LX_SHADOW_RESULT__PHASE_SD0_LO 0x0FBD +#define VL53LX_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 0x0FBE +#define VL53LX_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_HI 0x= 0FBE +#define VL53LX_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_LO 0x= 0FBF +#define VL53LX_SHPEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 0x0FC0 +#define VL53LX_SHPEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_HI 0x= 0FC0 +#define VL53LX_SHPEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_LO 0x= 0FC1 +#define VL53LX_SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0 0x0FC2 +#define VL53LX_SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_HI 0x0FC2 +#define VL53LX_SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0_LO 0x0FC3 +#define VL53LX_SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0 0x0FC4 +#define VL53LX_SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_HI 0x0FC4 +#define VL53LX_SHADOW_RESULT__MM_OUTER_ACTUAL_EFFECTIVE_SPADS_SD0_LO 0x0FC5 +#define VL53LX_SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0 0x0FC6 +#define VL53LX_SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_HI 0x0FC6 +#define VL53LX_SHADOW_RESULT__AVG_SIGNAL_COUNT_RATE_MCPS_SD0_LO 0x0FC7 +#define VL53LX_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1 0x0FC8 +#define VL53LX_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_HI 0x0FC8 +#define VL53LX_SHADOW_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD1_LO 0x0FC9 +#define VL53LX_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1 0x0FCA +#define VL53LX_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_HI 0x0FCA +#define VL53LX_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_LO 0x0FCB +#define VL53LX_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1 0x0FCC +#define VL53LX_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_HI 0x0FCC +#define VL53LX_SHADOW_RESULT__AMBIENT_COUNT_RATE_MCPS_SD1_LO 0x0FCD +#define VL53LX_SHADOW_RESULT__SIGMA_SD1 0x0FCE +#define VL53LX_SHADOW_RESULT__SIGMA_SD1_HI 0x0FCE +#define VL53LX_SHADOW_RESULT__SIGMA_SD1_LO 0x0FCF +#define VL53LX_SHADOW_RESULT__PHASE_SD1 0x0FD0 +#define VL53LX_SHADOW_RESULT__PHASE_SD1_HI 0x0FD0 +#define VL53LX_SHADOW_RESULT__PHASE_SD1_LO 0x0FD1 +#define VL53LX_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1 0x0FD2 +#define VL53LX_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_HI 0x= 0FD2 +#define VL53LX_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_LO 0x= 0FD3 +#define VL53LX_SHADOW_RESULT__SPARE_0_SD1 0x0FD4 +#define VL53LX_SHADOW_RESULT__SPARE_0_SD1_HI 0x0FD4 +#define VL53LX_SHADOW_RESULT__SPARE_0_SD1_LO 0x0FD5 +#define VL53LX_SHADOW_RESULT__SPARE_1_SD1 0x0FD6 +#define VL53LX_SHADOW_RESULT__SPARE_1_SD1_HI 0x0FD6 +#define VL53LX_SHADOW_RESULT__SPARE_1_SD1_LO 0x0FD7 +#define VL53LX_SHADOW_RESULT__SPARE_2_SD1 0x0FD8 +#define VL53LX_SHADOW_RESULT__SPARE_2_SD1_HI 0x0FD8 +#define VL53LX_SHADOW_RESULT__SPARE_2_SD1_LO 0x0FD9 +#define VL53LX_SHADOW_RESULT__SPARE_3_SD1 0x0FDA +#define VL53LX_SHADOW_RESULT__THRESH_INFO 0x0FDB +#define VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0 0x0FDC +#define VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_3 0x0FDC +#define VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_2 0x0FDD +#define VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_1 0x0FDE +#define VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD0_0 0x0FDF +#define VL53LX_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0 0x0FE0 +#define VL53LX_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_3 0x0FE0 +#define VL53LX_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_2 0x0FE1 +#define VL53LX_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_1 0x0FE2 +#define VL53LX_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD0_0 0x0FE3 +#define VL53LX_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0 0x0FE4 +#define VL53LX_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_3 0x0FE4 +#define VL53LX_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_2 0x0FE5 +#define VL53LX_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_1 0x0FE6 +#define VL53LX_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD0_0 0x0FE7 +#define VL53LX_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0 0x0FE8 +#define VL53LX_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_3 0x0FE8 +#define VL53LX_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_2 0x0FE9 +#define VL53LX_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_1 0x0FEA +#define VL53LX_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD0_0 0x0FEB +#define VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1 0x0FEC +#define VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_3 0x0FEC +#define VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_2 0x0FED +#define VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_1 0x0FEE +#define VL53LX_SHADOW_RESULT_CORE__AMBIENT_WINDOW_EVENTS_SD1_0 0x0FEF +#define VL53LX_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1 0x0FF0 +#define VL53LX_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_3 0x0FF0 +#define VL53LX_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_2 0x0FF1 +#define VL53LX_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_1 0x0FF2 +#define VL53LX_SHADOW_RESULT_CORE__RANGING_TOTAL_EVENTS_SD1_0 0x0FF3 +#define VL53LX_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1 0x0FF4 +#define VL53LX_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_3 0x0FF4 +#define VL53LX_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_2 0x0FF5 +#define VL53LX_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_1 0x0FF6 +#define VL53LX_SHADOW_RESULT_CORE__SIGNAL_TOTAL_EVENTS_SD1_0 0x0FF7 +#define VL53LX_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1 0x0FF8 +#define VL53LX_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_3 0x0FF8 +#define VL53LX_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_2 0x0FF9 +#define VL53LX_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_1 0x0FFA +#define VL53LX_SHADOW_RESULT_CORE__TOTAL_PERIODS_ELAPSED_SD1_0 0x0FFB +#define VL53LX_SHADOW_RESULT_CORE__SPARE_0 0x0FFC +#define VL53LX_SHADOW_PHASECAL_RESULT__REFERENCE_PHASE_HI 0x0FFE +#define VL53LX_SHADOW_PHASECAL_RESULT__REFERENCE_PHASE_LO 0x0FFF + +#define VL53LX_HISTOGRAM_CONFIG__OPCODE_SEQUENCE_0 VL53LX_SIGMA_ESTIMATOR_= _EFFECTIVE_PULSE_WIDTH_NS +#define VL53LX_HISTOGRAM_CONFIG__OPCODE_SEQUENCE_1 VL53LX_SIGMA_ESTIMATOR_= _EFFECTIVE_AMBIENT_WIDTH_NS +#define VL53LX_HISTOGRAM_CONFIG__OPCODE_SEQUENCE_2 VL53LX_SIGMA_ESTIMATOR_= _SIGMA_REF_MM +#define VL53LX_HISTOGRAM_CONFIG__AMB_THRESH_HIGH VL53LX_ALGO__RANGE_IGNORE= _THRESHOLD_MCPS + +#define VL53LX_RESULT__HISTOGRAM_BIN_0_2 0x0= 08E +#define VL53LX_RESULT__HISTOGRAM_BIN_0_1 0x0= 08F +#define VL53LX_RESULT__HISTOGRAM_BIN_0_0 0x0= 090 +#define VL53LX_RESULT__HISTOGRAM_BIN_23_2 0x0= 0D3 +#define VL53LX_RESULT__HISTOGRAM_BIN_23_1 0x0= 0D4 +#define VL53LX_RESULT__HISTOGRAM_BIN_23_0 0x0= 0D5 +#define VL53LX_RESULT__HISTOGRAM_BIN_23_0_MSB 0x0= 0D9 +#define VL53LX_RESULT__HISTOGRAM_BIN_23_0_LSB 0x0= 0DA + +#define VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX VL53LX_RESULT__INTERRUPT= _STATUS +#define VL53LX_HISTOGRAM_BIN_DATA_I2C_SIZE_BYTES (VL53LX_RESULT__HISTOGRA= M_BIN_23_0_LSB - VL53LX_RESULT__INTERRUPT_STATUS + 1) + +#define VL53LX_TUNINGPARM_VERSION_DEFAULT \ +((uint16_t) 30) +#define VL53LX_TUNINGPARM_KEY_TABLE_VERSION_DEFAULT \ +((uint16_t) 14) +#define VL53LX_TUNINGPARM_LLD_VERSION_DEFAULT \ +((uint16_t) 12180) +#define VL53LX_TUNINGPARM_HIST_ALGO_SELECT_DEFAULT \ +((uint8_t) 4) +#define VL53LX_TUNINGPARM_HIST_TARGET_ORDER_DEFAULT \ +((uint8_t) 1) +#define VL53LX_TUNINGPARM_HIST_FILTER_WOI_0_DEFAULT \ +((uint8_t) 1) +#define VL53LX_TUNINGPARM_HIST_FILTER_WOI_1_DEFAULT \ +((uint8_t) 2) +#define VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD_DEFAULT \ +((uint8_t) 1) +#define VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0_DEFAULT \ +((uint8_t) 80) +#define VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1_DEFAULT \ +((uint8_t) 100) +#define VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS_DEFAULT \ +((int32_t) 16) +#define VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER_DEFAULT \ +((uint16_t) 4157) +#define VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD_DEFAULT \ +((uint16_t) 50) +#define VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT_DEFAULT \ +((int32_t) 100) +#define VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM_DEFAULT \ +((uint8_t) 1) +#define VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM_DEFAULT \ +((uint16_t) 180) +#define VL53LX_TUNINGPARM_HIST_GAIN_FACTOR_DEFAULT \ +((uint16_t) 2020) +#define VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE_DEFAULT \ +((uint8_t) 8) +#define VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM_DEFAULT \ +((uint16_t) 0) +#define VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_DEFAULT \ +((uint8_t) 0) +#define VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT_DEFA= ULT \ +((uint16_t) 2048) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE_DEFAULT \ +((uint8_t) 9) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE_DEFAULT \ +((uint8_t) 5) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE_DEFAULT \ +((uint8_t) 3) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE_DEFAULT \ +((uint8_t) 6) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE_DEFAULT \ +((uint8_t) 6) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE_DEFAULT \ +((uint8_t) 6) +#define VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM_DEFAULT \ +((int16_t) -50) +#define VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM_DEFAULT \ +((int16_t) 50) +#define VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM_DEFAULT \ +((uint16_t) 140) +#define VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE_DEFAULT \ +((uint16_t) 50) +#define VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS_DEFAULT \ +((uint16_t) 400) +#define VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA_DEFAULT \ +((uint8_t) 80) +#define VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE_DEFAULT \ +((uint8_t) 2) +#define VL53LX_TUNINGPARM_PHASECAL_TARGET_DEFAULT \ +((uint8_t) 33) +#define VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE_DEFAULT \ +((uint16_t) 0) +#define VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR_DEFAULT \ +((uint16_t) 2011) +#define VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM_DEFAULT \ +((uint8_t) 0) +#define VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM_DEFAULT \ +((uint16_t) 60) +#define VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM_DEFAULT \ +((uint16_t) 60) +#define VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM_DEFAULT \ +((uint16_t) 60) +#define VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS_DEFAULT \ +((uint16_t) 128) +#define VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS_DEFAULT \ +((uint16_t) 128) +#define VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS_DEFAULT \ +((uint16_t) 128) +#define VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH_DEFAULT \ +((uint8_t) 8) +#define VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS_DEFAULT \ +((uint8_t) 16) +#define VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM_DEFAULT \ +((uint8_t) 1) +#define VL53LX_TUNINGPARM_LITE_RIT_MULT_DEFAULT \ +((uint8_t) 64) +#define VL53LX_TUNINGPARM_LITE_SEED_CONFIG_DEFAULT \ +((uint8_t) 2) +#define VL53LX_TUNINGPARM_LITE_QUANTIFIER_DEFAULT \ +((uint8_t) 2) +#define VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT_DEFAULT \ +((uint8_t) 0) +#define VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE_DEFAULT \ +((uint8_t) 14) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE_DEFAULT \ +((uint8_t) 10) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE_DEFAULT \ +((uint8_t) 6) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE_DEFAULT \ +((uint8_t) 14) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE_DEFAULT \ +((uint8_t) 10) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE_DEFAULT \ +((uint8_t) 6) +#define VL53LX_TUNINGPARM_TIMED_SEED_CONFIG_DEFAULT \ +((uint8_t) 1) +#define VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA_DEFAULT \ +((uint8_t) 32) +#define VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0_DEFAULT \ +((uint16_t) 15) +#define VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1_DEFAULT \ +((uint16_t) 52) +#define VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2_DEFAULT \ +((uint16_t) 200) +#define VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3_DEFAULT \ +((uint16_t) 364) +#define VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4_DEFAULT \ +((uint16_t) 400) +#define VL53LX_TUNINGPARM_VHV_LOOPBOUND_DEFAULT \ +((uint8_t) 129) +#define VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE_DEFAULT \ +((uint8_t) 8) +#define VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD_DEFAULT \ +((uint8_t) 11) +#define VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US_DEFAULT \ +((uint32_t) 1000) +#define VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS_DEFAULT \ +((uint16_t) 2560) +#define VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS_DEFAULT \ +((uint16_t) 1280) +#define VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS_DEFAULT \ +((uint16_t) 5120) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES_DEFAULT \ +((uint8_t) 7) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM_DEFAULT \ +((int16_t) -70) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM_DEFAULT \ +((int16_t) 70) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS_DEFAULT \ +((uint16_t) 5120) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US_DEFAULT \ +((uint32_t) 15000) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS_DEFAULT \ +((uint16_t) 640) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM_DEFAULT \ +((uint16_t) 140) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US_DEFAULT \ +((uint32_t) 2000) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US_DEFAULT \ +((uint32_t) 10000) +#define VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS_DEFAULT \ +((uint16_t) 2560) +#define VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US_DEFAULT \ +((uint32_t) 15000) +#define VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US_DEFAULT \ +((uint32_t) 13000) +#define VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US_DEFAULT \ +((uint32_t) 13000) +#define VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES_DEFAULT \ +((uint8_t) 8) +#define VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES_DEFAULT \ +((uint8_t) 40) +#define VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES_DEFAULT \ +((uint8_t) 9) +#define VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS_DEFAULT \ +((uint16_t) 5120) +#define VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US_DEFAULT \ +((uint32_t) 15000) +#define VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US_DEFAULT \ +((uint32_t) 2000) +#define VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES_DEFAULT \ +((uint16_t) 16) +#define VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US_DEFAULT \ +((uint32_t) 1000) +#define VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES_DEFAULT \ +((uint16_t) 8) +#define VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD_DEFAULT \ +((uint8_t) 18) +#define VL53LX_TUNINGPARM_SPADMAP_VCSEL_START_DEFAULT \ +((uint8_t) 15) +#define VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS_DEFAULT \ +((uint16_t) 12) +#define VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT \ +((uint16_t) 2560) +#define VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAUL= T \ +((uint16_t) 2560) +#define VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT \ +((uint16_t) 5120) +#define VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT \ +((uint16_t) 2560) +#define VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 1000) +#define VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 15000) +#define VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 15000) +#define VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT= \ +((uint32_t) 15000) +#define VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 15000) +#define VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 9000) +#define VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 6000) +#define VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 1000) +#define VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 2000) +#define VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 2000) +#define VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 2000) +#define VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 2000) +#define VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 63000) +#define VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 2500) +#define VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 2500) +#define VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 13000) +#define VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN_DEFAULT \ +((uint16_t) 0) +#define VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN_DEFAULT \ +((uint32_t) 100) +#define VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_DEFAULT \ +((uint32_t) 0) +#define VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI_DEFAULT \ +((uint8_t) 0) +#define VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT_DEFAULT \ +((uint32_t) 200) +#define VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA_DEFAULT \ +((uint32_t) 2048) +#define VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA_DEFAULT \ +((uint32_t) 308) +#define VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT_DEFAULT \ +((uint32_t) 10240) +#define VL53LX_TUNINGPARM_DYNXTALK_SCALER_CALC_METHOD_DEFAULT \ +((uint8_t) 0) +#define VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER_DEFAULT \ +((int16_t) 256) +#define VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER_DEFAULT \ +((int16_t) 256) +#define VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET_DEFAULT \ +((uint8_t) 0) +#define VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY_DEFAULT \ +((uint8_t) 0) +#define VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD_DEFAULT \ +((uint32_t) 128) +#define VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS_DEFAULT \ +((uint32_t) 57671680) +#define VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT_DEFAULT \ +((uint32_t) 40) +#define VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS_DEFAULT \ +((uint32_t) 410) +#define VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM_DEFAULT \ +((uint16_t) 900) +#define VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND_DEFAULT \ +((uint8_t) 3) +#define VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 1) +#define VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US_DEFAULT \ +((uint32_t) 8000) +#define VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS_DEFAULT \ +((uint16_t) 10240) +#define VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER_DEFAULT \ +((uint32_t) 1) +#define VL53LX_TUNINGPARM_HIST_MERGE_DEFAULT \ +((uint8_t) 1) +#define VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD_DEFAULT \ +((uint32_t) 15000) +#define VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE_DEFAULT \ +((uint8_t) 6) +#define VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR_DEFAULT \ +((uint32_t) 2000) +#define VL53LX_TUNINGPARM_UWR_ENABLE_DEFAULT \ +((uint8_t) 1) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MIN_DEFAULT \ +((int16_t) 2000) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MAX_DEFAULT \ +((int16_t) 2750) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MIN_DEFAULT \ +((int16_t) 250) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MAX_DEFAULT \ +((int16_t) 1000) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MIN_DEFAULT \ +((int16_t) 1250) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MAX_DEFAULT \ +((int16_t) 1750) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MIN_DEFAULT \ +((int16_t) 1250) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MAX_DEFAULT \ +((int16_t) 1750) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MIN_DEFAULT \ +((int16_t) -200) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MAX_DEFAULT \ +((int16_t) 200) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEA_DEFAULT \ +((int16_t) 2360) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEB_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEA_DEFAULT \ +((int16_t) 2375) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEB_DEFAULT \ +((int16_t) 3125) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEA_DEFAULT \ +((int16_t) 4720) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEB_DEFAULT \ +((int16_t) 3230) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEA_DEFAULT \ +((int16_t) 4750) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEB_DEFAULT \ +((int16_t) 6350) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEA_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEB_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MIN_DEFAULT \ +((int16_t) 250) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MAX_DEFAULT \ +((int16_t) 1250) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MIN_DEFAULT \ +((int16_t) 3250) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MAX_DEFAULT \ +((int16_t) 4500) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MIN_DEFAULT \ +((int16_t) -200) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MAX_DEFAULT \ +((int16_t) 200) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MIN_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MAX_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MIN_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MAX_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEA_DEFAULT \ +((int16_t) 3850) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEB_DEFAULT \ +((int16_t) 4600) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEA_DEFAULT \ +((int16_t) 3850) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEB_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEA_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEB_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEA_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEB_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEA_DEFAULT \ +((int16_t) 0) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEB_DEFAULT \ +((int16_t) 0) + +#define VL53LX_IOCTL_START _IO('p', 0x01) + +#define VL53LX_IOCTL_STOP _IO('p', 0x05) + +#define VL53LX_IOCTL_PARAMETER \ + _IOWR('p', 0x0d, struct stmvl53lx_parameter) + +#define VL53LX_IOCTL_ROI\ + _IOWR('p', 0x0e, struct stmvl53lx_ioctl_roi_t) + +#define VL53LX_IOCTL_MZ_DATA\ + _IOR('p', 0x0f, VL53LX_MultiRangingData_t) + +#define VL53LX_IOCTL_MZ_DATA_BLOCKING\ + _IOR('p', 0x11, VL53LX_MultiRangingData_t) + +#define VL53LX_IOCTL_CALIBRATION_DATA\ + _IOWR('p', 0x12, struct stmvl53lx_ioctl_calibration_data_t) + +#define VL53LX_IOCTL_PERFORM_CALIBRATION\ + _IOW('p', 0x13, struct stmvl53lx_ioctl_perform_calibration_t) + + + +struct stmvl53lx_register { + uint32_t is_read; + uint32_t index; + uint32_t cnt; + int32_t status; + union reg_data_t { + uint8_t b; + uint16_t w; + uint32_t dw; + uint8_t bytes[256]; + } data; +}; + +struct stmvl53lx_register_flexi { + uint32_t is_read; + uint32_t index; + uint32_t cnt; + int32_t status; + uint8_t data[]; +}; + +#define VL53LX_IOCTL_REGISTER _IOWR('p', 0x0c, struct stmvl53lx_register) + +#define VL53LX_IOCTL_MZ_DATA_ADDITIONAL\ + _IOR('p', 0x15, struct stmvl53lx_data_with_additional) + +#define VL53LX_IOCTL_MZ_DATA_ADDITIONAL_BLOCKING\ + _IOR('p', 0x16, struct stmvl53lx_data_with_additional) + +#define VL53LX_NVM_POWER_UP_DELAY_US 50 +#define VL53LX_NVM_READ_TRIGGER_DELAY_US 5 +#define VL53LX_NVM__IDENTIFICATION__MODEL_ID 0x0008 +#define VL53LX_NVM__IDENTIFICATION__MODULE_TYPE 0x000C +#define VL53LX_NVM__IDENTIFICATION__REVISION_ID 0x000D +#define VL53LX_NVM__IDENTIFICATION__MODULE_ID 0x000E +#define VL53LX_NVM__I2C_VALID 0x0010 +#define VL53LX_NVM__I2C_SLAVE__DEVICE_ADDRESS 0x0011 +#define VL53LX_NVM__EWS__OSC_MEASURED__FAST_OSC_FREQUENCY 0x0014 +#define VL53LX_NVM__EWS__FAST_OSC_TRIM_MAX 0x0016 +#define VL53LX_NVM__EWS__FAST_OSC_FREQ_SET 0x0017 +#define VL53LX_NVM__EWS__SLOW_OSC_CALIBRATION 0x0018 +#define VL53LX_NVM__FMT__OSC_MEASURED__FAST_OSC_FREQUENCY 0x001C +#define VL53LX_NVM__FMT__FAST_OSC_TRIM_MAX 0x001E +#define VL53LX_NVM__FMT__FAST_OSC_FREQ_SET 0x001F +#define VL53LX_NVM__FMT__SLOW_OSC_CALIBRATION 0x0020 +#define VL53LX_NVM__VHV_CONFIG_UNLOCK 0x0028 +#define VL53LX_NVM__REF_SELVDDPIX 0x0029 +#define VL53LX_NVM__REF_SELVQUENCH 0x002A +#define VL53LX_NVM__REGAVDD1V2_SEL_REGDVDD1V2_SEL 0x002B +#define VL53LX_NVM__VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND 0x002C +#define VL53LX_NVM__VHV_CONFIG__COUNT_THRESH 0x002D +#define VL53LX_NVM__VHV_CONFIG__OFFSET 0x002E +#define VL53LX_NVM__VHV_CONFIG__INIT 0x002F +#define VL53LX_NVM__LASER_SAFETY__VCSEL_TRIM_LL 0x0030 +#define VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_LL 0x0031 +#define VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_MAX_LL 0x0032 +#define VL53LX_NVM__LASER_SAFETY__MULT_LL 0x0034 +#define VL53LX_NVM__LASER_SAFETY__CLIP_LL 0x0035 +#define VL53LX_NVM__LASER_SAFETY__VCSEL_TRIM_LD 0x0038 +#define VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_LD 0x0039 +#define VL53LX_NVM__LASER_SAFETY__VCSEL_SELION_MAX_LD 0x003A +#define VL53LX_NVM__LASER_SAFETY__MULT_LD 0x003C +#define VL53LX_NVM__LASER_SAFETY__CLIP_LD 0x003D +#define VL53LX_NVM__LASER_SAFETY_LOCK_BYTE 0x0040 +#define VL53LX_NVM__LASER_SAFETY_UNLOCK_BYTE 0x0044 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_0_ 0x0048 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_1_ 0x0049 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_2_ 0x004A +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_3_ 0x004B +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_4_ 0x004C +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_5_ 0x004D +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_6_ 0x004E +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_7_ 0x004F +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_8_ 0x0050 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_9_ 0x0051 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_10_ 0x0052 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_11_ 0x0053 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_12_ 0x0054 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_13_ 0x0055 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_14_ 0x0056 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_15_ 0x0057 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_16_ 0x0058 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_17_ 0x0059 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_18_ 0x005A +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_19_ 0x005B +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_20_ 0x005C +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_21_ 0x005D +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_22_ 0x005E +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_23_ 0x005F +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_24_ 0x0060 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_25_ 0x0061 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_26_ 0x0062 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_27_ 0x0063 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_28_ 0x0064 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_29_ 0x0065 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_30_ 0x0066 +#define VL53LX_NVM__EWS__SPAD_ENABLES_RTN_31_ 0x0067 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC1_0_ 0x0068 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC1_1_ 0x0069 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC1_2_ 0x006A +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC1_3_ 0x006B +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC1_4_ 0x006C +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC1_5_ 0x006D +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC2_0_ 0x0070 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC2_1_ 0x0071 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC2_2_ 0x0072 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC2_3_ 0x0073 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC2_4_ 0x0074 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC2_5_ 0x0075 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC3_0_ 0x0078 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC3_1_ 0x0079 +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC3_2_ 0x007A +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC3_3_ 0x007B +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC3_4_ 0x007C +#define VL53LX_NVM__EWS__SPAD_ENABLES_REF__LOC3_5_ 0x007D +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_0_ 0x0080 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_1_ 0x0081 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_2_ 0x0082 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_3_ 0x0083 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_4_ 0x0084 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_5_ 0x0085 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_6_ 0x0086 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_7_ 0x0087 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_8_ 0x0088 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_9_ 0x0089 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_10_ 0x008A +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_11_ 0x008B +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_12_ 0x008C +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_13_ 0x008D +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_14_ 0x008E +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_15_ 0x008F +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_16_ 0x0090 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_17_ 0x0091 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_18_ 0x0092 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_19_ 0x0093 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_20_ 0x0094 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_21_ 0x0095 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_22_ 0x0096 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_23_ 0x0097 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_24_ 0x0098 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_25_ 0x0099 +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_26_ 0x009A +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_27_ 0x009B +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_28_ 0x009C +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_29_ 0x009D +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_30_ 0x009E +#define VL53LX_NVM__FMT__SPAD_ENABLES_RTN_31_ 0x009F +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC1_0_ 0x00A0 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC1_1_ 0x00A1 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC1_2_ 0x00A2 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC1_3_ 0x00A3 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC1_4_ 0x00A4 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC1_5_ 0x00A5 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC2_0_ 0x00A8 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC2_1_ 0x00A9 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC2_2_ 0x00AA +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC2_3_ 0x00AB +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC2_4_ 0x00AC +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC2_5_ 0x00AD +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC3_0_ 0x00B0 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC3_1_ 0x00B1 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC3_2_ 0x00B2 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC3_3_ 0x00B3 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC3_4_ 0x00B4 +#define VL53LX_NVM__FMT__SPAD_ENABLES_REF__LOC3_5_ 0x00B5 +#define VL53LX_NVM__FMT__ROI_CONFIG__MODE_ROI_CENTRE_SPAD 0x00B8 +#define VL53LX_NVM__FMT__ROI_CONFIG__MODE_ROI_XY_SIZE 0x00B9 +#define VL53LX_NVM__FMT__REF_SPAD_APPLY__NUM_REQUESTED_REF_SPAD 0x00BC +#define VL53LX_NVM__FMT__REF_SPAD_MAN__REF_LOCATION 0x00BD +#define VL53LX_NVM__FMT__MM_CONFIG__INNER_OFFSET_MM 0x00C0 +#define VL53LX_NVM__FMT__MM_CONFIG__OUTER_OFFSET_MM 0x00C2 +#define VL53LX_NVM__FMT__ALGO__PART_TO_PART_RANGE_OFFSET_MM 0x00C4 +#define VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS 0x= 00C8 +#define VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCP= S 0x00CA +#define VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCP= S 0x00CC +#define VL53LX_NVM__FMT__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_0 0x00CE +#define VL53LX_NVM__FMT__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_1 0x00CF +#define VL53LX_NVM__CUSTOMER_NVM_SPACE_PROGRAMMED 0x00E0 +#define VL53LX_NVM__CUST__I2C_SLAVE__DEVICE_ADDRESS 0x00E4 +#define VL53LX_NVM__CUST__REF_SPAD_APPLY__NUM_REQUESTED_REF_SPAD 0x00E8 +#define VL53LX_NVM__CUST__REF_SPAD_MAN__REF_LOCATION 0x00E9 +#define VL53LX_NVM__CUST__MM_CONFIG__INNER_OFFSET_MM 0x00EC +#define VL53LX_NVM__CUST__MM_CONFIG__OUTER_OFFSET_MM 0x00EE +#define VL53LX_NVM__CUST__ALGO__PART_TO_PART_RANGE_OFFSET_MM 0x00F0 +#define VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS 0= x00F4 +#define VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KC= PS 0x00F6 +#define VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KC= PS 0x00F8 +#define VL53LX_NVM__CUST__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_0 0x00FA +#define VL53LX_NVM__CUST__SPARE_HOST_CONFIG__NVM_CONFIG_SPARE_1 0x00FB +#define VL53LX_NVM__FMT__FGC__BYTE_0 0x01DC +#define VL53LX_NVM__FMT__FGC__BYTE_1 0x01DD +#define VL53LX_NVM__FMT__FGC__BYTE_2 0x01DE +#define VL53LX_NVM__FMT__FGC__BYTE_3 0x01DF +#define VL53LX_NVM__FMT__FGC__BYTE_4 0x01E0 +#define VL53LX_NVM__FMT__FGC__BYTE_5 0x01E1 +#define VL53LX_NVM__FMT__FGC__BYTE_6 0x01E2 +#define VL53LX_NVM__FMT__FGC__BYTE_7 0x01E3 +#define VL53LX_NVM__FMT__FGC__BYTE_8 0x01E4 +#define VL53LX_NVM__FMT__FGC__BYTE_9 0x01E5 +#define VL53LX_NVM__FMT__FGC__BYTE_10 0x01E6 +#define VL53LX_NVM__FMT__FGC__BYTE_11 0x01E7 +#define VL53LX_NVM__FMT__FGC__BYTE_12 0x01E8 +#define VL53LX_NVM__FMT__FGC__BYTE_13 0x01E9 +#define VL53LX_NVM__FMT__FGC__BYTE_14 0x01EA +#define VL53LX_NVM__FMT__FGC__BYTE_15 0x01EB +#define VL53LX_NVM__FMT__TEST_PROGRAM_MAJOR_MINOR 0x01EC +#define VL53LX_NVM__FMT__MAP_MAJOR_MINOR 0x01ED +#define VL53LX_NVM__FMT__YEAR_MONTH 0x01EE +#define VL53LX_NVM__FMT__DAY_MODULE_DATE_PHASE 0x01EF +#define VL53LX_NVM__FMT__TIME 0x01F0 +#define VL53LX_NVM__FMT__TESTER_ID 0x01F2 +#define VL53LX_NVM__FMT__SITE_ID 0x01F3 +#define VL53LX_NVM__EWS__TEST_PROGRAM_MAJOR_MINOR 0x01F4 +#define VL53LX_NVM__EWS__PROBE_CARD_MAJOR_MINOR 0x01F5 +#define VL53LX_NVM__EWS__TESTER_ID 0x01F6 +#define VL53LX_NVM__EWS__LOT__BYTE_0 0x01F8 +#define VL53LX_NVM__EWS__LOT__BYTE_1 0x01F9 +#define VL53LX_NVM__EWS__LOT__BYTE_2 0x01FA +#define VL53LX_NVM__EWS__LOT__BYTE_3 0x01FB +#define VL53LX_NVM__EWS__LOT__BYTE_4 0x01FC +#define VL53LX_NVM__EWS__LOT__BYTE_5 0x01FD +#define VL53LX_NVM__EWS__WAFER 0x01FD +#define VL53LX_NVM__EWS__XCOORD 0x01FE +#define VL53LX_NVM__EWS__YCOORD 0x01FF +#define VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_INDEX 0x00B8 +#define VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE 4 +#define VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_INDEX 0x015C +#define VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE 56 +#define VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_INDEX 0x0194 +#define VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE 8 +#define VL53LX_NVM__FMT__RANGE_RESULTS__140MM_MM_PRE_RANGE 0x019C +#define VL53LX_NVM__FMT__RANGE_RESULTS__140MM_DARK 0x01AC +#define VL53LX_NVM__FMT__RANGE_RESULTS__400MM_DARK 0x01BC +#define VL53LX_NVM__FMT__RANGE_RESULTS__400MM_AMBIENT 0x01CC +#define VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES 16 + + +typedef uint8_t VL53LX_SmudgeCorrectionModes; +#define VL53LX_SMUDGE_CORRECTION_NONE ((VL53LX_SmudgeCorrectionModes= ) 0) +#define VL53LX_SMUDGE_CORRECTION_CONTINUOUS ((VL53LX_SmudgeCorrectionModes= ) 1) +#define VL53LX_SMUDGE_CORRECTION_SINGLE ((VL53LX_SmudgeCorrectionModes= ) 2) +#define VL53LX_SMUDGE_CORRECTION_DEBUG ((VL53LX_SmudgeCorrectionModes= ) 3) + +typedef uint8_t VL53LX_OffsetCorrectionModes; +#define VL53LX_OFFSETCORRECTIONMODE_STANDARD ((VL53LX_OffsetCorrectionMode= s) 1) +#define VL53LX_OFFSETCORRECTIONMODE_PERVCSEL ((VL53LX_OffsetCorrectionMode= s) 3) + +typedef int8_t VL53LX_Error; + +#define VL53LX_ERROR_NONE ((VL53LX_Error) 0) +#define VL53LX_ERROR_CALIBRATION_WARNING ((VL53LX_Error) - 1) +#define VL53LX_ERROR_MIN_CLIPPED ((VL53LX_Error) - 2) +#define VL53LX_ERROR_UNDEFINED ((VL53LX_Error) - 3) +#define VL53LX_ERROR_INVALID_PARAMS ((VL53LX_Error) - 4) +#define VL53LX_ERROR_NOT_SUPPORTED ((VL53LX_Error) - 5) +#define VL53LX_ERROR_RANGE_ERROR ((VL53LX_Error) - 6) +#define VL53LX_ERROR_TIME_OUT ((VL53LX_Error) - 7) +#define VL53LX_ERROR_MODE_NOT_SUPPORTED ((VL53LX_Error) - 8) +#define VL53LX_ERROR_BUFFER_TOO_SMALL ((VL53LX_Error) - 9) +#define VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL ((VL53LX_Error) - 1= 0) +#define VL53LX_ERROR_GPIO_NOT_EXISTING ((VL53LX_Error) - 1= 1) +#define VL53LX_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED ((VL53LX_Error) - 1= 2) +#define VL53LX_ERROR_CONTROL_INTERFACE ((VL53LX_Error) - 1= 3) +#define VL53LX_ERROR_INVALID_COMMAND ((VL53LX_Error) - 1= 4) +#define VL53LX_ERROR_DIVISION_BY_ZERO ((VL53LX_Error) - 1= 5) +#define VL53LX_ERROR_REF_SPAD_INIT ((VL53LX_Error) - 1= 6) +#define VL53LX_ERROR_GPH_SYNC_CHECK_FAIL ((VL53LX_Error) - 1= 7) +#define VL53LX_ERROR_STREAM_COUNT_CHECK_FAIL ((VL53LX_Error) - 1= 8) +#define VL53LX_ERROR_GPH_ID_CHECK_FAIL ((VL53LX_Error) - 1= 9) +#define VL53LX_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL ((VL53LX_Error) - 2= 0) +#define VL53LX_ERROR_ZONE_GPH_ID_CHECK_FAIL ((VL53LX_Error) - 2= 1) +#define VL53LX_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL ((VL53LX_Error) - 2= 2) +#define VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL ((VL53LX_Error) - 2= 3) +#define VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL ((VL53LX_Error) -= 24) +#define VL53LX_ERROR_OFFSET_CAL_NO_SPADS_ENABLED_FAIL ((VL53LX_Error) -= 25) +#define VL53LX_ERROR_ZONE_CAL_NO_SAMPLE_FAIL ((VL53LX_Error) -= 26) +#define VL53LX_ERROR_TUNING_PARM_KEY_MISMATCH ((VL53LX_Error) = - 27) +#define VL53LX_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS ((VL53LX_Error) - = 28) +#define VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH ((VL53LX_Error) - = 29) +#define VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW ((VL53LX_Error) - = 30) +#define VL53LX_WARNING_OFFSET_CAL_MISSING_SAMPLES ((VL53LX_Error) - = 31) +#define VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH ((VL53LX_Error) - = 32) +#define VL53LX_WARNING_OFFSET_CAL_RATE_TOO_HIGH ((VL53LX_Error) - = 33) +#define VL53LX_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW ((VL53LX_Error) - = 34) +#define VL53LX_WARNING_ZONE_CAL_MISSING_SAMPLES ((VL53LX_Error) - 35) +#define VL53LX_WARNING_ZONE_CAL_SIGMA_TOO_HIGH ((VL53LX_Error) - 36) +#define VL53LX_WARNING_ZONE_CAL_RATE_TOO_HIGH ((VL53LX_Error) - 37) +#define VL53LX_WARNING_XTALK_MISSING_SAMPLES ((VL53LX_Error) -= 38) +#define VL53LX_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT ((VL53LX_Error) -= 39) +#define VL53LX_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT ((VL53LX_Error) -= 40) +#define VL53LX_ERROR_NOT_IMPLEMENTED ((VL53LX_Error) - 4= 1) +#define VL53LX_ERROR_PLATFORM_SPECIFIC_START ((VL53LX_Error) - 6= 0) + +#define VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS 0x8000 +#define VL53LX_TUNINGPARM_PRIVATE_PAGE_BASE_ADDRESS 0xC000 + +#define VL53LX_CALIBRATION_REF_SPAD 0 +#define VL53LX_CALIBRATION_CROSSTALK 1 +#define VL53LX_CALIBRATION_OFFSET 2 +#define VL53LX_CALIBRATION_OFFSET_SIMPLE 4 +#define VL53LX_CALIBRATION_OFFSET_PER_VCSEL 5 +#define VL53LX_CALIBRATION_OFFSET_ZERO_DISTANCE 6 + +typedef uint8_t VL53LX_DeviceZonePreset; + +typedef uint8_t VL53LX_DevicePresetModes; + +#define VL53LX_DEVICEPRESETMODE_NONE \ + ((VL53LX_DevicePresetModes) 0) +#define VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE \ + ((VL53LX_DevicePresetModes) 27) +#define VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE \ + ((VL53LX_DevicePresetModes) 30) +#define VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE \ + ((VL53LX_DevicePresetModes) 33) + +typedef uint8_t VL53LX_DeviceMeasurementModes; + +#define VL53LX_DEVICEMEASUREMENTMODE_STOP \ + ((VL53LX_DeviceMeasurementModes) 0x00) +#define VL53LX_DEVICEMEASUREMENTMODE_SINGLESHOT \ + ((VL53LX_DeviceMeasurementModes) 0x10) +#define VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK \ + ((VL53LX_DeviceMeasurementModes) 0x20) +#define VL53LX_DEVICEMEASUREMENTMODE_TIMED \ + ((VL53LX_DeviceMeasurementModes) 0x40) +#define VL53LX_DEVICEMEASUREMENTMODE_ABORT \ + ((VL53LX_DeviceMeasurementModes) 0x80) + +typedef uint8_t VL53LX_OffsetCalibrationMode; + +#define VL53LX_OFFSETCALIBRATIONMODE__NONE \ + ((VL53LX_OffsetCalibrationMode) 0) +#define VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD \ + ((VL53LX_OffsetCalibrationMode) 1) +#define VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM \ + ((VL53LX_OffsetCalibrationMode) 2) +#define VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY \ + ((VL53LX_OffsetCalibrationMode) 3) +#define VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__HISTOGRAM_PRE_RANGE_ONLY \ + ((VL53LX_OffsetCalibrationMode) 4) + +typedef uint8_t VL53LX_OffsetCorrectionMode; + +#define VL53LX_OFFSETCORRECTIONMODE__NONE \ + ((VL53LX_OffsetCorrectionMode) 0) +#define VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS \ + ((VL53LX_OffsetCorrectionMode) 1) +#define VL53LX_OFFSETCORRECTIONMODE__PER_VCSEL_OFFSETS \ + ((VL53LX_OffsetCorrectionMode) 3) + +typedef uint8_t VL53LX_DeviceDmaxMode; + +#define VL53LX_DEVICEDMAXMODE__NONE \ + ((VL53LX_DeviceDmaxMode) 0) +#define VL53LX_DEVICEDMAXMODE__FMT_CAL_DATA \ + ((VL53LX_DeviceDmaxMode) 1) +#define VL53LX_DEVICEDMAXMODE__CUST_CAL_DATA \ + ((VL53LX_DeviceDmaxMode) 2) + +typedef uint8_t VL53LX_DeviceState; + +#define VL53LX_DEVICESTATE_POWERDOWN ((VL53LX_DeviceState) 0) +#define VL53LX_DEVICESTATE_HW_STANDBY ((VL53LX_DeviceState) 1) +#define VL53LX_DEVICESTATE_FW_COLDBOOT ((VL53LX_DeviceState) 2) +#define VL53LX_DEVICESTATE_SW_STANDBY ((VL53LX_DeviceState) 3) +#define VL53LX_DEVICESTATE_RANGING_DSS_AUTO ((VL53LX_DeviceState) 4) +#define VL53LX_DEVICESTATE_RANGING_DSS_MANUAL ((VL53LX_DeviceState) 5) +#define VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC ((VL53LX_DeviceState) 6) +#define VL53LX_DEVICESTATE_RANGING_GATHER_DATA ((VL53LX_DeviceState) 7) +#define VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA ((VL53LX_DeviceState) 8) + +#define VL53LX_DEVICESTATE_UNKNOWN ((VL53LX_DeviceState) 98) +#define VL53LX_DEVICESTATE_ERROR ((VL53LX_DeviceState) 99) + +typedef uint8_t VL53LX_GPIO_Interrupt_Mode; + +#define VL53LX_GPIOINTMODE_LEVEL_LOW \ + ((VL53LX_GPIO_Interrupt_Mode) 0) +#define VL53LX_GPIOINTMODE_LEVEL_HIGH \ + ((VL53LX_GPIO_Interrupt_Mode) 1) +#define VL53LX_GPIOINTMODE_OUT_OF_WINDOW \ + ((VL53LX_GPIO_Interrupt_Mode) 2) +#define VL53LX_GPIOINTMODE_IN_WINDOW \ + ((VL53LX_GPIO_Interrupt_Mode) 3) + +typedef uint8_t VL53LX_DeviceSscArray; + +#define VL53LX_DEVICESSCARRAY_RTN ((VL53LX_DeviceSscArray) 0x00) + +#define VL53LX_DEVICETESTMODE_REF ((VL53LX_DeviceSscArray) 0x01) + +typedef uint8_t VL53LX_HistAlgoSelect; + +#define VL53LX_HIST_ALGO_SELECT__PW_HIST_GEN1 \ + ((VL53LX_HistAlgoSelect) 1) +#define VL53LX_HIST_ALGO_SELECT__PW_HIST_GEN2 \ + ((VL53LX_HistAlgoSelect) 2) +#define VL53LX_HIST_ALGO_SELECT__PW_HIST_GEN3 \ + ((VL53LX_HistAlgoSelect) 3) +#define VL53LX_HIST_ALGO_SELECT__PW_HIST_GEN4 \ + ((VL53LX_HistAlgoSelect) 4) + + +typedef uint8_t VL53LX_HistTargetOrder; + +#define VL53LX_HIST_TARGET_ORDER__INCREASING_DISTANCE \ + ((VL53LX_HistTargetOrder) 1) +#define VL53LX_HIST_TARGET_ORDER__STRONGEST_FIRST \ + ((VL53LX_HistTargetOrder) 2) + +typedef uint8_t VL53LX_HistAmbEstMethod; + +#define VL53LX_HIST_AMB_EST_METHOD__AMBIENT_BINS \ + ((VL53LX_HistAmbEstMethod) 1) +#define VL53LX_HIST_AMB_EST_METHOD__THRESHOLDED_BINS \ + ((VL53LX_HistAmbEstMethod) 2) + +typedef uint16_t VL53LX_TuningParms; + +#define VL53LX_TUNINGPARMS_LLD_PUBLIC_MIN_ADDRESS \ + ((VL53LX_TuningParms) VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS) +#define VL53LX_TUNINGPARMS_LLD_PUBLIC_MAX_ADDRESS \ + ((VL53LX_TuningParms) VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEB) + +#define VL53LX_TUNINGPARMS_LLD_PRIVATE_MIN_ADDRESS \ + ((VL53LX_TuningParms) VL53LX_TUNINGPARM_PRIVATE_PAGE_BASE_ADDRESS) +#define VL53LX_TUNINGPARMS_LLD_PRIVATE_MAX_ADDRESS \ + ((VL53LX_TuningParms) VL53LX_TUNINGPARMS_LLD_PRIVATE_MIN_ADDRESS) + +typedef uint8_t VL53LX_DistanceModes; + +#define VL53LX_DISTANCEMODE_SHORT ((VL53LX_DistanceModes) 1) +#define VL53LX_DISTANCEMODE_MEDIUM ((VL53LX_DistanceModes) 2) +#define VL53LX_DISTANCEMODE_LONG ((VL53LX_DistanceModes) 3) + +typedef uint8_t VL53LX_DeviceInterruptPolarity; + +#define VL53LX_DEVICEINTERRUPTPOLARITY_ACTIVE_HIGH \ + ((VL53LX_DeviceInterruptPolarity) 0x00) +#define VL53LX_DEVICEINTERRUPTPOLARITY_ACTIVE_LOW \ + ((VL53LX_DeviceInterruptPolarity) 0x10) +#define VL53LX_DEVICEINTERRUPTPOLARITY_BIT_MASK \ + ((VL53LX_DeviceInterruptPolarity) 0x10) +#define VL53LX_DEVICEINTERRUPTPOLARITY_CLEAR_MASK \ + ((VL53LX_DeviceInterruptPolarity) 0xEF) + +typedef uint8_t VL53LX_ZoneConfig_BinConfig_select; + +#define VL53LX_ZONECONFIG_BINCONFIG__LOWAMB \ + ((VL53LX_ZoneConfig_BinConfig_select) 1) +#define VL53LX_ZONECONFIG_BINCONFIG__MIDAMB \ + ((VL53LX_ZoneConfig_BinConfig_select) 2) +#define VL53LX_ZONECONFIG_BINCONFIG__HIGHAMB \ + ((VL53LX_ZoneConfig_BinConfig_select) 3) + +typedef uint8_t VL53LX_DeviceConfigLevel; + +#define VL53LX_DEVICECONFIGLEVEL_SYSTEM_CONTROL \ + ((VL53LX_DeviceConfigLevel) 0) + +#define VL53LX_DEVICECONFIGLEVEL_DYNAMIC_ONWARDS \ + ((VL53LX_DeviceConfigLevel) 1) + +#define VL53LX_DEVICECONFIGLEVEL_TIMING_ONWARDS \ + ((VL53LX_DeviceConfigLevel) 2) + +#define VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS \ + ((VL53LX_DeviceConfigLevel) 3) + +#define VL53LX_DEVICECONFIGLEVEL_STATIC_ONWARDS \ + ((VL53LX_DeviceConfigLevel) 4) + +#define VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS \ + ((VL53LX_DeviceConfigLevel) 5) + +#define VL53LX_DEVICECONFIGLEVEL_FULL \ + ((VL53LX_DeviceConfigLevel) 6) + +typedef uint8_t VL53LX_DeviceResultsLevel; + +#define VL53LX_DEVICERESULTSLEVEL_SYSTEM_RESULTS \ + ((VL53LX_DeviceResultsLevel) 0) + +#define VL53LX_DEVICERESULTSLEVEL_UPTO_CORE \ + ((VL53LX_DeviceResultsLevel) 1) + +#define VL53LX_DEVICERESULTSLEVEL_FULL \ + ((VL53LX_DeviceResultsLevel) 2) + +typedef uint8_t VL53LX_DeviceReportStatus; + +#define VL53LX_DEVICEREPORTSTATUS_NOUPDATE \ + ((VL53LX_DeviceReportStatus) 0) + +#define VL53LX_DEVICEREPORTSTATUS_ROI_SETUP \ + ((VL53LX_DeviceReportStatus) 1) +#define VL53LX_DEVICEREPORTSTATUS_VHV \ + ((VL53LX_DeviceReportStatus) 2) +#define VL53LX_DEVICEREPORTSTATUS_PHASECAL \ + ((VL53LX_DeviceReportStatus) 3) +#define VL53LX_DEVICEREPORTSTATUS_REFERENCE_PHASE \ + ((VL53LX_DeviceReportStatus) 4) +#define VL53LX_DEVICEREPORTSTATUS_DSS1 \ + ((VL53LX_DeviceReportStatus) 5) +#define VL53LX_DEVICEREPORTSTATUS_DSS2 \ + ((VL53LX_DeviceReportStatus) 6) +#define VL53LX_DEVICEREPORTSTATUS_MM1 \ + ((VL53LX_DeviceReportStatus) 7) +#define VL53LX_DEVICEREPORTSTATUS_MM2 \ + ((VL53LX_DeviceReportStatus) 8) +#define VL53LX_DEVICEREPORTSTATUS_RANGE \ + ((VL53LX_DeviceReportStatus) 9) +#define VL53LX_DEVICEREPORTSTATUS_HISTOGRAM \ + ((VL53LX_DeviceReportStatus) 10) + +typedef uint8_t VL53LX_DeviceGpioMode; + +#define VL53LX_DEVICEGPIOMODE_OUTPUT_CONSTANT_ZERO \ + ((VL53LX_DeviceGpioMode) 0x00) +#define VL53LX_DEVICEGPIOMODE_OUTPUT_RANGE_AND_ERROR_INTERRUPTS \ + ((VL53LX_DeviceGpioMode) 0x01) +#define VL53LX_DEVICEGPIOMODE_OUTPUT_TIMIER_INTERRUPTS \ + ((VL53LX_DeviceGpioMode) 0x02) +#define VL53LX_DEVICEGPIOMODE_OUTPUT_RANGE_MODE_INTERRUPT_STATUS \ + ((VL53LX_DeviceGpioMode) 0x03) +#define VL53LX_DEVICEGPIOMODE_OUTPUT_SLOW_OSCILLATOR_CLOCK \ + ((VL53LX_DeviceGpioMode) 0x04) +#define VL53LX_DEVICEGPIOMODE_BIT_MASK \ + ((VL53LX_DeviceGpioMode) 0x0F) +#define VL53LX_DEVICEGPIOMODE_CLEAR_MASK \ + ((VL53LX_DeviceGpioMode) 0xF0) + +typedef uint8_t VL53LX_DeviceDssMode; + +#define VL53LX_DEVICEDSSMODE__DISABLED \ + ((VL53LX_DeviceDssMode) 0) +#define VL53LX_DEVICEDSSMODE__TARGET_RATE \ + ((VL53LX_DeviceDssMode) 1) +#define VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS \ + ((VL53LX_DeviceDssMode) 2) +#define VL53LX_DEVICEDSSMODE__BLOCK_SELECT \ + ((VL53LX_DeviceDssMode) 3) + +typedef uint8_t VL53LX_DeviceTestMode; + +#define VL53LX_DEVICETESTMODE_NONE \ + ((VL53LX_DeviceTestMode) 0x00) +#define VL53LX_DEVICETESTMODE_NVM_ZERO \ + ((VL53LX_DeviceTestMode) 0x01) +#define VL53LX_DEVICETESTMODE_NVM_COPY \ + ((VL53LX_DeviceTestMode) 0x02) +#define VL53LX_DEVICETESTMODE_PATCH \ + ((VL53LX_DeviceTestMode) 0x03) +#define VL53LX_DEVICETESTMODE_DCR \ + ((VL53LX_DeviceTestMode) 0x04) +#define VL53LX_DEVICETESTMODE_LCR_VCSEL_OFF \ + ((VL53LX_DeviceTestMode) 0x05) +#define VL53LX_DEVICETESTMODE_LCR_VCSEL_ON \ + ((VL53LX_DeviceTestMode) 0x06) +#define VL53LX_DEVICETESTMODE_SPOT_CENTRE_LOCATE \ + ((VL53LX_DeviceTestMode) 0x07) +#define VL53LX_DEVICETESTMODE_REF_SPAD_CHAR_WITH_PRE_VHV \ + ((VL53LX_DeviceTestMode) 0x08) +#define VL53LX_DEVICETESTMODE_REF_SPAD_CHAR_ONLY \ + ((VL53LX_DeviceTestMode) 0x09) + +#define VL53LX_SEQUENCE_VHV_EN 0x01 +#define VL53LX_SEQUENCE_PHASECAL_EN 0x02 +#define VL53LX_SEQUENCE_REFERENCE_PHASE_EN 0x04 +#define VL53LX_SEQUENCE_DSS1_EN 0x08 +#define VL53LX_SEQUENCE_DSS2_EN 0x10 +#define VL53LX_SEQUENCE_MM1_EN 0x20 +#define VL53LX_SEQUENCE_MM2_EN 0x40 +#define VL53LX_SEQUENCE_RANGE_EN 0x80 + +#define VL53LX_INTERRUPT_CONFIG_LEVEL_LOW 0x00 +#define VL53LX_INTERRUPT_CONFIG_LEVEL_HIGH 0x01 +#define VL53LX_INTERRUPT_CONFIG_OUT_OF_WINDOW 0x02 +#define VL53LX_INTERRUPT_CONFIG_IN_WINDOW 0x03 +#define VL53LX_INTERRUPT_CONFIG_NEW_SAMPLE_READY 0x20 + +#define VL53LX_CLEAR_RANGE_INT 0x01 +#define VL53LX_CLEAR_ERROR_INT 0x02 + +#define VL53LX_DEVICESCHEDULERMODE_PSEUDO_SOLO 0x00 +#define VL53LX_DEVICESCHEDULERMODE_STREAMING 0x01 +#define VL53LX_DEVICESCHEDULERMODE_HISTOGRAM 0x02 + +#define VL53LX_DEVICEREADOUTMODE_SINGLE_SD (0x00 << 2) +#define VL53LX_DEVICEREADOUTMODE_DUAL_SD (0x01 << 2) +#define VL53LX_DEVICEREADOUTMODE_SPLIT_READOUT (0x02 << 2) +#define VL53LX_DEVICEREADOUTMODE_SPLIT_MANUAL (0x03 << 2) + +#define VL53LX_TUNINGPARM_VERSION \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 0)) +#define VL53LX_TUNINGPARM_KEY_TABLE_VERSION \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 1)) +#define VL53LX_TUNINGPARM_LLD_VERSION \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 2)) +#define VL53LX_TUNINGPARM_HIST_ALGO_SELECT \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 3)) +#define VL53LX_TUNINGPARM_HIST_TARGET_ORDER \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 4)) +#define VL53LX_TUNINGPARM_HIST_FILTER_WOI_0 \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 5)) +#define VL53LX_TUNINGPARM_HIST_FILTER_WOI_1 \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 6)) +#define VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 7)) +#define VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0 \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 8)) +#define VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1 \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 9)) +#define VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 10)) +#define VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 11)) +#define VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 12)) +#define VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 13)) +#define VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 14)) +#define VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 15)) +#define VL53LX_TUNINGPARM_HIST_GAIN_FACTOR \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 16)) +#define VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 17)) +#define VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 18)) +#define VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 19)) +#define VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 20)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 21)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 22)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 23)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 24)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 25)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 26)) +#define VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 27)) +#define VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 28)) +#define VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 29)) +#define VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 30)) +#define VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 31)) +#define VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 32)) +#define VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 33)) +#define VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 34)) +#define VL53LX_TUNINGPARM_PHASECAL_TARGET \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 35)) +#define VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 36)) +#define VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 37)) +#define VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 38)) +#define VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 39)) +#define VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 40)) +#define VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 41)) +#define VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 42)) +#define VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 43)) +#define VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 44)) +#define VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 45)) +#define VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 46)) +#define VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 47)) +#define VL53LX_TUNINGPARM_LITE_RIT_MULT \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 48)) +#define VL53LX_TUNINGPARM_LITE_SEED_CONFIG \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 49)) +#define VL53LX_TUNINGPARM_LITE_QUANTIFIER \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 50)) +#define VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 51)) +#define VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 52)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 53)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 54)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 55)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 56)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 57)) +#define VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 58)) +#define VL53LX_TUNINGPARM_TIMED_SEED_CONFIG \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 59)) +#define VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 60)) +#define VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0 \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 61)) +#define VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1 \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 62)) +#define VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2 \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 63)) +#define VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3 \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 64)) +#define VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4 \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 65)) +#define VL53LX_TUNINGPARM_VHV_LOOPBOUND \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 66)) +#define VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 67)) +#define VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 68)) +#define VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 69)) +#define VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 70)) +#define VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 71)) +#define VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 72)) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 73)) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 74)) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 75)) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 76)) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 77)) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 78)) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 79)) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 80)) +#define VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 81)) +#define VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 82)) +#define VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 83)) +#define VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 84)) +#define VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 85)) +#define VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 86)) +#define VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 87)) +#define VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 88)) +#define VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 89)) +#define VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 90)) +#define VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 91)) +#define VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 92)) +#define VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 93)) +#define VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 94)) +#define VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 95)) +#define VL53LX_TUNINGPARM_SPADMAP_VCSEL_START \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 96)) +#define VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 97)) +#define VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 98)) +#define VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 99)) +#define VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 100)) +#define VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 101)) +#define VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 102)) +#define VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 103)) +#define VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 104)) +#define VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 105)) +#define VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 106)) +#define VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 107)) +#define VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 108)) +#define VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 109)) +#define VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 110)) +#define VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 111)) +#define VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 112)) +#define VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 113)) +#define VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 114)) +#define VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 115)) +#define VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 116)) +#define VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 117)) +#define VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 118)) +#define VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 119)) +#define VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 120)) +#define VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 121)) +#define VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 122)) +#define VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 123)) +#define VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 124)) +#define VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 125)) +#define VL53LX_TUNINGPARM_DYNXTALK_SCALER_CALC_METHOD \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 126)) +#define VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 127)) +#define VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 128)) +#define VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 129)) +#define VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 130)) +#define VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 131)) +#define VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 132)) +#define VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 133)) +#define VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 134)) +#define VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 135)) +#define VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 136)) +#define VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 137)) +#define VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 138)) +#define VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 139)) +#define VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 140)) +#define VL53LX_TUNINGPARM_HIST_MERGE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 141)) +#define VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 142)) +#define VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 143)) +#define VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 144)) +#define VL53LX_TUNINGPARM_UWR_ENABLE \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 145)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 146)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MAX \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 147)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 148)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MAX \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 149)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 150)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MAX \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 151)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 152)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MAX \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 153)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 154)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MAX \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 155)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 156)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEB \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 157)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 158)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEB \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 159)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 160)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEB \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 161)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 162)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEB \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 163)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 164)) +#define VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEB \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 165)) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 166)) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MAX \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 167)) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 168)) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MAX \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 169)) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 170)) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MAX \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 171)) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 172)) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MAX \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 173)) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MIN \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 174)) +#define VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MAX \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 175)) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 176)) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEB \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 177)) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 178)) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEB \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 179)) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 180)) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEB \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 181)) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 182)) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEB \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 183)) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEA \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 184)) +#define VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEB \ +((VL53LX_TuningParms) (VL53LX_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS + 185)) + +enum VL53LX_Tuning_t { + VL53LX_TUNING_VERSION =3D 0, + VL53LX_TUNING_PROXY_MIN, + VL53LX_TUNING_SINGLE_TARGET_XTALK_TARGET_DISTANCE_MM, + VL53LX_TUNING_SINGLE_TARGET_XTALK_SAMPLE_NUMBER, + VL53LX_TUNING_MIN_AMBIENT_DMAX_VALID, + VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER, + VL53LX_TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM, + VL53LX_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT, + VL53LX_TUNING_XTALK_FULL_ROI_BIN_SUM_MARGIN, + VL53LX_TUNING_XTALK_FULL_ROI_DEFAULT_OFFSET, + VL53LX_TUNING_ZERO_DISTANCE_OFFSET_NON_LINEAR_FACTOR, + VL53LX_TUNING_MAX_TUNABLE_KEY +}; + +#define TUNING_VERSION 0x0007 +#define TUNING_PROXY_MIN -30 +#define TUNING_SINGLE_TARGET_XTALK_TARGET_DISTANCE_MM 600 +#define TUNING_SINGLE_TARGET_XTALK_SAMPLE_NUMBER 50 +#define TUNING_MIN_AMBIENT_DMAX_VALID 8 +#ifdef SMALL_FOOTPRINT +#define TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER 50 +#else +#define TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER 10 +#endif +#define TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM 600 +#ifdef SMALL_FOOTPRINT +#define TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT 1 +#else +#define TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT 3 +#endif +#define TUNING_ZERO_DISTANCE_OFFSET_NON_LINEAR_FACTOR_DEFAULT 9 +#define TUNING_XTALK_FULL_ROI_BIN_SUM_MARGIN 24 +#define TUNING_XTALK_FULL_ROI_DEFAULT_OFFSET 50 + +#ifdef STMVL53LX_DEBUG_I2C +#define i2c_debug(fmt, ...) printk(fmt, ##__VA_ARGS__) +#else +#define i2c_debug(fmt, ...) ((void)0) +#endif + +#if STMVL53LX_LOG_POLL_TIMING +#define poll_timing_log(ptv) printk("poll in %d us\n", tv_elapsed_us(ptv)) +#else +#define poll_timing_log(...) ((void)0) +#endif + +#define IMPLEMENT_PARAMETER_INTEGER(sysfs_name, info_name)\ +static ssize_t stmvl53lx_show_##sysfs_name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); \ + int param; \ +\ + mutex_lock(&data->work_mutex); \ + param =3D data->sysfs_name; \ + mutex_unlock(&data->work_mutex);; \ +\ + return scnprintf(buf, PAGE_SIZE, "%d\n", param); \ +} \ +\ +static ssize_t stmvl53lx_store_##sysfs_name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); \ + int rc =3D 0; \ + int param; \ +\ + mutex_lock(&data->work_mutex); \ +\ + if (kstrtoint(buf, 0, ¶m)) { \ + vl53lx_errmsg("invalid syntax in %s", buf); \ + rc =3D -EINVAL; \ + } else \ + rc =3D stmvl53lx_set_##sysfs_name(data, param); \ +\ + mutex_unlock(&data->work_mutex); \ +\ + return rc ? rc : count; \ +} \ +\ +static int ctrl_param_##sysfs_name(struct stmvl53lx_data *data, \ + struct stmvl53lx_parameter *param) \ +{ \ + int rc =3D 0; \ +\ + if (param->is_read) { \ + param->value =3D data->sysfs_name; \ + param->status =3D 0; \ + vl53lx_dbgmsg("get " info_name " %d", param->value); \ + rc =3D 0; \ + } else { \ + rc =3D stmvl53lx_set_##sysfs_name(data, param->value); \ + vl53lx_dbgmsg("rc %d req %d now %d", rc, \ + param->value, data->sysfs_name); \ + } \ +\ + return rc; \ +} + +typedef struct { + uint32_t VL53LX_p_016; + uint32_t VL53LX_p_017; + uint16_t VL53LX_p_011; + uint8_t range_status; +} VL53LX_object_data_t; + +typedef struct { + VL53LX_DeviceState cfg_device_state; + VL53LX_DeviceState rd_device_state; + uint8_t zone_id; + uint8_t stream_count; + uint8_t max_objects; + uint8_t active_objects; + VL53LX_object_data_t VL53LX_p_003[VL53LX_MAX_RANGE_RESULTS]; + VL53LX_object_data_t xmonitor; +} VL53LX_zone_objects_t; + +typedef struct { + uint32_t ll_revision; + uint8_t ll_major; + uint8_t ll_minor; + uint8_t ll_build; +} VL53LX_ll_version_t; + +typedef struct { + VL53LX_DeviceState cfg_device_state; + uint8_t cfg_stream_count; + uint8_t cfg_internal_stream_count; + uint8_t cfg_internal_stream_count_val; + uint8_t cfg_gph_id; + uint8_t cfg_timing_status; + uint8_t cfg_zone_id; + VL53LX_DeviceState rd_device_state; + uint8_t rd_stream_count; + uint8_t rd_internal_stream_count; + uint8_t rd_internal_stream_count_val; + uint8_t rd_gph_id; + uint8_t rd_timing_status; + uint8_t rd_zone_id; +} VL53LX_ll_driver_state_t; + +typedef struct { + VL53LX_GPIO_Interrupt_Mode intr_mode_distance; + VL53LX_GPIO_Interrupt_Mode intr_mode_rate; + uint8_t intr_new_measure_ready; + uint8_t intr_no_target; + uint8_t intr_combined_mode; + uint16_t threshold_distance_high; + uint16_t threshold_distance_low; + uint16_t threshold_rate_high; + uint16_t threshold_rate_low; +} VL53LX_GPIO_interrupt_config_t; + +typedef struct { + uint16_t tp_tuning_parm_version; + uint16_t tp_tuning_parm_key_table_version; + uint16_t tp_tuning_parm_lld_version; + uint8_t tp_init_phase_rtn_lite_long; + uint8_t tp_init_phase_rtn_lite_med; + uint8_t tp_init_phase_rtn_lite_short; + uint8_t tp_init_phase_ref_lite_long; + uint8_t tp_init_phase_ref_lite_med; + uint8_t tp_init_phase_ref_lite_short; + uint8_t tp_init_phase_rtn_hist_long; + uint8_t tp_init_phase_rtn_hist_med; + uint8_t tp_init_phase_rtn_hist_short; + uint8_t tp_init_phase_ref_hist_long; + uint8_t tp_init_phase_ref_hist_med; + uint8_t tp_init_phase_ref_hist_short; + uint8_t tp_consistency_lite_phase_tolerance; + uint8_t tp_phasecal_target; + uint16_t tp_cal_repeat_rate; + uint8_t tp_lite_min_clip; + uint16_t tp_lite_long_sigma_thresh_mm; + uint16_t tp_lite_med_sigma_thresh_mm; + uint16_t tp_lite_short_sigma_thresh_mm; + uint16_t tp_lite_long_min_count_rate_rtn_mcps; + uint16_t tp_lite_med_min_count_rate_rtn_mcps; + uint16_t tp_lite_short_min_count_rate_rtn_mcps; + uint8_t tp_lite_sigma_est_pulse_width_ns; + uint8_t tp_lite_sigma_est_amb_width_ns; + uint8_t tp_lite_sigma_ref_mm; + uint8_t tp_lite_seed_cfg; + uint8_t tp_timed_seed_cfg; + uint8_t tp_lite_quantifier; + uint8_t tp_lite_first_order_select; + uint16_t tp_dss_target_lite_mcps; + uint16_t tp_dss_target_histo_mcps; + uint16_t tp_dss_target_histo_mz_mcps; + uint16_t tp_dss_target_timed_mcps; + uint16_t tp_dss_target_very_short_mcps; + uint32_t tp_phasecal_timeout_lite_us; + uint32_t tp_phasecal_timeout_hist_long_us; + uint32_t tp_phasecal_timeout_hist_med_us; + uint32_t tp_phasecal_timeout_hist_short_us; + uint32_t tp_phasecal_timeout_mz_long_us; + uint32_t tp_phasecal_timeout_mz_med_us; + uint32_t tp_phasecal_timeout_mz_short_us; + uint32_t tp_phasecal_timeout_timed_us; + uint32_t tp_mm_timeout_lite_us; + uint32_t tp_mm_timeout_histo_us; + uint32_t tp_mm_timeout_mz_us; + uint32_t tp_mm_timeout_timed_us; + uint32_t tp_mm_timeout_lpa_us; + uint32_t tp_range_timeout_lite_us; + uint32_t tp_range_timeout_histo_us; + uint32_t tp_range_timeout_mz_us; + uint32_t tp_range_timeout_timed_us; + uint32_t tp_range_timeout_lpa_us; + uint32_t tp_phasecal_patch_power; + uint8_t tp_hist_merge; + uint32_t tp_reset_merge_threshold; + uint8_t tp_hist_merge_max_size; + uint8_t tp_uwr_enable; + int16_t tp_uwr_med_z_1_min; + int16_t tp_uwr_med_z_1_max; + int16_t tp_uwr_med_z_2_min; + int16_t tp_uwr_med_z_2_max; + int16_t tp_uwr_med_z_3_min; + int16_t tp_uwr_med_z_3_max; + int16_t tp_uwr_med_z_4_min; + int16_t tp_uwr_med_z_4_max; + int16_t tp_uwr_med_z_5_min; + int16_t tp_uwr_med_z_5_max; + int16_t tp_uwr_med_corr_z_1_rangea; + int16_t tp_uwr_med_corr_z_1_rangeb; + int16_t tp_uwr_med_corr_z_2_rangea; + int16_t tp_uwr_med_corr_z_2_rangeb; + int16_t tp_uwr_med_corr_z_3_rangea; + int16_t tp_uwr_med_corr_z_3_rangeb; + int16_t tp_uwr_med_corr_z_4_rangea; + int16_t tp_uwr_med_corr_z_4_rangeb; + int16_t tp_uwr_med_corr_z_5_rangea; + int16_t tp_uwr_med_corr_z_5_rangeb; + int16_t tp_uwr_lng_z_1_min; + int16_t tp_uwr_lng_z_1_max; + int16_t tp_uwr_lng_z_2_min; + int16_t tp_uwr_lng_z_2_max; + int16_t tp_uwr_lng_z_3_min; + int16_t tp_uwr_lng_z_3_max; + int16_t tp_uwr_lng_z_4_min; + int16_t tp_uwr_lng_z_4_max; + int16_t tp_uwr_lng_z_5_min; + int16_t tp_uwr_lng_z_5_max; + int16_t tp_uwr_lng_corr_z_1_rangea; + int16_t tp_uwr_lng_corr_z_1_rangeb; + int16_t tp_uwr_lng_corr_z_2_rangea; + int16_t tp_uwr_lng_corr_z_2_rangeb; + int16_t tp_uwr_lng_corr_z_3_rangea; + int16_t tp_uwr_lng_corr_z_3_rangeb; + int16_t tp_uwr_lng_corr_z_4_rangea; + int16_t tp_uwr_lng_corr_z_4_rangeb; + int16_t tp_uwr_lng_corr_z_5_rangea; + int16_t tp_uwr_lng_corr_z_5_rangeb; +} VL53LX_tuning_parm_storage_t; + +typedef struct { + uint8_t device_test_mode; + uint8_t VL53LX_p_005; + uint32_t timeout_us; + uint16_t target_count_rate_mcps; + uint16_t min_count_rate_limit_mcps; + uint16_t max_count_rate_limit_mcps; +} VL53LX_refspadchar_config_t; + +typedef struct { + VL53LX_DeviceSscArray array_select; + uint8_t VL53LX_p_005; + uint8_t vcsel_start; + uint8_t vcsel_width; + uint32_t timeout_us; + uint16_t rate_limit_mcps; +} VL53LX_ssc_config_t; + +typedef struct { + VL53LX_HistAlgoSelect hist_algo_select; + VL53LX_HistTargetOrder hist_target_order; + uint8_t filter_woi0; + uint8_t filter_woi1; + VL53LX_HistAmbEstMethod hist_amb_est_method; + uint8_t ambient_thresh_sigma0; + uint8_t ambient_thresh_sigma1; + uint16_t ambient_thresh_events_scaler; + int32_t min_ambient_thresh_events; + uint16_t noise_threshold; + int32_t signal_total_events_limit; + uint8_t sigma_estimator__sigma_ref_mm; + uint16_t sigma_thresh; + int16_t range_offset_mm; + uint16_t gain_factor; + uint8_t valid_phase_low; + uint8_t valid_phase_high; + uint8_t algo__consistency_check__phase_tolerance; + uint8_t algo__consistency_check__event_sigma; + uint16_t algo__consistency_check__event_min_spad_count; + uint16_t algo__consistency_check__min_max_tolerance; + uint8_t algo__crosstalk_compensation_enable; + uint32_t algo__crosstalk_compensation_plane_offset_kcps; + int16_t algo__crosstalk_compensation_x_plane_gradient_kcps; + int16_t algo__crosstalk_compensation_y_plane_gradient_kcps; + int16_t algo__crosstalk_detect_min_valid_range_mm; + int16_t algo__crosstalk_detect_max_valid_range_mm; + uint16_t algo__crosstalk_detect_max_valid_rate_kcps; + uint16_t algo__crosstalk_detect_max_sigma_mm; + uint8_t algo__crosstalk_detect_event_sigma; + uint16_t algo__crosstalk_detect_min_max_tolerance; +} VL53LX_hist_post_process_config_t; + +typedef struct { + uint8_t signal_thresh_sigma; + uint8_t ambient_thresh_sigma; + int32_t min_ambient_thresh_events; + int32_t signal_total_events_limit; + uint16_t target_reflectance_for_dmax_calc[VL53LX_MAX_AMBIENT_DMAX_VALUES= ]; + uint16_t max_effective_spads; + uint16_t dss_config__target_total_rate_mcps; + uint8_t dss_config__aperture_attenuation; +} VL53LX_hist_gen3_dmax_config_t; + +typedef struct { + uint16_t dss_config__target_total_rate_mcps; + uint32_t phasecal_config_timeout_us; + uint32_t mm_config_timeout_us; + uint32_t range_config_timeout_us; + uint8_t num_of_samples; + int16_t algo__crosstalk_extract_min_valid_range_mm; + int16_t algo__crosstalk_extract_max_valid_range_mm; + uint16_t algo__crosstalk_extract_max_valid_rate_kcps; + uint16_t algo__crosstalk_extract_max_sigma_mm; +} VL53LX_xtalkextract_config_t; + +typedef struct { + uint32_t algo__crosstalk_compensation_plane_offset_kcps; + int16_t algo__crosstalk_compensation_x_plane_gradient_kcps; + int16_t algo__crosstalk_compensation_y_plane_gradient_kcps; + uint32_t nvm_default__crosstalk_compensation_plane_offset_kcps; + int16_t nvm_default__crosstalk_compensation_x_plane_gradient_kcps; + int16_t nvm_default__crosstalk_compensation_y_plane_gradient_kcps; + uint8_t global_crosstalk_compensation_enable; + int16_t histogram_mode_crosstalk_margin_kcps; + int16_t lite_mode_crosstalk_margin_kcps; + uint8_t crosstalk_range_ignore_threshold_mult; + uint16_t crosstalk_range_ignore_threshold_rate_mcps; + int16_t algo__crosstalk_detect_min_valid_range_mm; + int16_t algo__crosstalk_detect_max_valid_range_mm; + uint16_t algo__crosstalk_detect_max_valid_rate_kcps; + uint16_t algo__crosstalk_detect_max_sigma_mm; +} VL53LX_xtalk_config_t; + +typedef struct { + uint16_t dss_config__target_total_rate_mcps; + uint32_t phasecal_config_timeout_us; + uint32_t range_config_timeout_us; + uint32_t mm_config_timeout_us; + uint8_t pre_num_of_samples; + uint8_t mm1_num_of_samples; + uint8_t mm2_num_of_samples; +} VL53LX_offsetcal_config_t; + +typedef struct { + uint16_t dss_config__target_total_rate_mcps; + uint32_t phasecal_config_timeout_us; + uint32_t mm_config_timeout_us; + uint32_t range_config_timeout_us; + uint16_t phasecal_num_of_samples; + uint16_t zone_num_of_samples; +} VL53LX_zonecal_config_t; + +typedef struct { + uint8_t global_config__spad_enables_ref_0; + uint8_t global_config__spad_enables_ref_1; + uint8_t global_config__spad_enables_ref_2; + uint8_t global_config__spad_enables_ref_3; + uint8_t global_config__spad_enables_ref_4; + uint8_t global_config__spad_enables_ref_5; + uint8_t global_config__ref_en_start_select; + uint8_t ref_spad_man__num_requested_ref_spads; + uint8_t ref_spad_man__ref_location; + uint16_t algo__crosstalk_compensation_plane_offset_kcps; + int16_t algo__crosstalk_compensation_x_plane_gradient_kcps; + int16_t algo__crosstalk_compensation_y_plane_gradient_kcps; + uint16_t ref_spad_char__total_rate_target_mcps; + int16_t algo__part_to_part_range_offset_mm; + int16_t mm_config__inner_offset_mm; + int16_t mm_config__outer_offset_mm; +} VL53LX_customer_nvm_managed_t; + +typedef struct { + int16_t cal_distance_mm; + uint16_t cal_reflectance_pc; + uint16_t max_samples; + uint16_t width; + uint16_t height; + uint16_t peak_rate_mcps[VL53LX_NVM_PEAK_RATE_MAP_SAMPLES]; +} VL53LX_cal_peak_rate_map_t; + +typedef struct { + uint16_t result__mm_inner_actual_effective_spads; + uint16_t result__mm_outer_actual_effective_spads; + uint16_t result__mm_inner_peak_signal_count_rtn_mcps; + uint16_t result__mm_outer_peak_signal_count_rtn_mcps; +} VL53LX_additional_offset_cal_data_t; + +typedef struct { + uint16_t ref__actual_effective_spads; + uint16_t ref__peak_signal_count_rate_mcps; + uint16_t ref__distance_mm; + uint16_t ref_reflectance_pc; + uint16_t coverglass_transmission; +} VL53LX_dmax_calibration_data_t; + +typedef struct { + uint16_t standard_ranging_gain_factor; + uint16_t histogram_ranging_gain_factor; +} VL53LX_gain_calibration_data_t; + +typedef struct { + uint8_t x_centre; + uint8_t y_centre; + uint8_t width; + uint8_t height; +} VL53LX_user_zone_t; + +typedef struct { + uint8_t x_centre; + uint8_t y_centre; +} VL53LX_optical_centre_t; + +typedef struct { + uint8_t histogram_config__spad_array_selection; + uint8_t histogram_config__low_amb_even_bin_0_1; + uint8_t histogram_config__low_amb_even_bin_2_3; + uint8_t histogram_config__low_amb_even_bin_4_5; + uint8_t histogram_config__low_amb_odd_bin_0_1; + uint8_t histogram_config__low_amb_odd_bin_2_3; + uint8_t histogram_config__low_amb_odd_bin_4_5; + uint8_t histogram_config__mid_amb_even_bin_0_1; + uint8_t histogram_config__mid_amb_even_bin_2_3; + uint8_t histogram_config__mid_amb_even_bin_4_5; + uint8_t histogram_config__mid_amb_odd_bin_0_1; + uint8_t histogram_config__mid_amb_odd_bin_2; + uint8_t histogram_config__mid_amb_odd_bin_3_4; + uint8_t histogram_config__mid_amb_odd_bin_5; + uint8_t histogram_config__user_bin_offset; + uint8_t histogram_config__high_amb_even_bin_0_1; + uint8_t histogram_config__high_amb_even_bin_2_3; + uint8_t histogram_config__high_amb_even_bin_4_5; + uint8_t histogram_config__high_amb_odd_bin_0_1; + uint8_t histogram_config__high_amb_odd_bin_2_3; + uint8_t histogram_config__high_amb_odd_bin_4_5; + uint16_t histogram_config__amb_thresh_low; + uint16_t histogram_config__amb_thresh_high; +} VL53LX_histogram_config_t; + +typedef struct { + uint8_t max_zones; + uint8_t active_zones; + VL53LX_histogram_config_t multizone_hist_cfg; + VL53LX_user_zone_t user_zones[VL53LX_MAX_USER_ZONES]; + uint8_t bin_config[VL53LX_MAX_USER_ZONES]; +} VL53LX_zone_config_t; + +typedef struct { + uint8_t i2c_slave__device_address; + uint8_t ana_config__vhv_ref_sel_vddpix; + uint8_t ana_config__vhv_ref_sel_vquench; + uint8_t ana_config__reg_avdd1v2_sel; + uint8_t ana_config__fast_osc__trim; + uint16_t osc_measured__fast_osc__frequency; + uint8_t vhv_config__timeout_macrop_loop_bound; + uint8_t vhv_config__count_thresh; + uint8_t vhv_config__offset; + uint8_t vhv_config__init; +} VL53LX_static_nvm_managed_t; + +typedef struct { + uint32_t VL53LX_p_037; + uint8_t VL53LX_p_063; + uint8_t VL53LX_p_064; + uint16_t VL53LX_p_065; + uint16_t VL53LX_p_066; + uint16_t VL53LX_p_067; + uint16_t VL53LX_p_038; + uint32_t VL53LX_p_009; + uint32_t VL53LX_p_033; + uint16_t VL53LX_p_034; + uint16_t VL53LX_p_004; + uint32_t VL53LX_p_028; + uint32_t VL53LX_p_035; + int16_t VL53LX_p_036; + int16_t VL53LX_p_022; +} VL53LX_hist_gen3_dmax_private_data_t; + +typedef struct { + uint16_t dss_config__target_total_rate_mcps; + uint8_t debug__ctrl; + uint8_t test_mode__ctrl; + uint8_t clk_gating__ctrl; + uint8_t nvm_bist__ctrl; + uint8_t nvm_bist__num_nvm_words; + uint8_t nvm_bist__start_address; + uint8_t host_if__status; + uint8_t pad_i2c_hv__config; + uint8_t pad_i2c_hv__extsup_config; + uint8_t gpio_hv_pad__ctrl; + uint8_t gpio_hv_mux__ctrl; + uint8_t gpio__tio_hv_status; + uint8_t gpio__fio_hv_status; + uint8_t ana_config__spad_sel_pswidth; + uint8_t ana_config__vcsel_pulse_width_offset; + uint8_t ana_config__fast_osc__config_ctrl; + uint8_t sigma_estimator__effective_pulse_width_ns; + uint8_t sigma_estimator__effective_ambient_width_ns; + uint8_t sigma_estimator__sigma_ref_mm; + uint8_t algo__crosstalk_compensation_valid_height_mm; + uint8_t spare_host_config__static_config_spare_0; + uint8_t spare_host_config__static_config_spare_1; + uint16_t algo__range_ignore_threshold_mcps; + uint8_t algo__range_ignore_valid_height_mm; + uint8_t algo__range_min_clip; + uint8_t algo__consistency_check__tolerance; + uint8_t spare_host_config__static_config_spare_2; + uint8_t sd_config__reset_stages_msb; + uint8_t sd_config__reset_stages_lsb; +} VL53LX_static_config_t; + +typedef struct { + uint8_t gph_config__stream_count_update_value; + uint8_t global_config__stream_divider; + uint8_t system__interrupt_config_gpio; + uint8_t cal_config__vcsel_start; + uint16_t cal_config__repeat_rate; + uint8_t global_config__vcsel_width; + uint8_t phasecal_config__timeout_macrop; + uint8_t phasecal_config__target; + uint8_t phasecal_config__override; + uint8_t dss_config__roi_mode_control; + uint16_t system__thresh_rate_high; + uint16_t system__thresh_rate_low; + uint16_t dss_config__manual_effective_spads_select; + uint8_t dss_config__manual_block_select; + uint8_t dss_config__aperture_attenuation; + uint8_t dss_config__max_spads_limit; + uint8_t dss_config__min_spads_limit; +} VL53LX_general_config_t; + +typedef struct { + uint8_t mm_config__timeout_macrop_a_hi; + uint8_t mm_config__timeout_macrop_a_lo; + uint8_t mm_config__timeout_macrop_b_hi; + uint8_t mm_config__timeout_macrop_b_lo; + uint8_t range_config__timeout_macrop_a_hi; + uint8_t range_config__timeout_macrop_a_lo; + uint8_t range_config__vcsel_period_a; + uint8_t range_config__timeout_macrop_b_hi; + uint8_t range_config__timeout_macrop_b_lo; + uint8_t range_config__vcsel_period_b; + uint16_t range_config__sigma_thresh; + uint16_t range_config__min_count_rate_rtn_limit_mcps; + uint8_t range_config__valid_phase_low; + uint8_t range_config__valid_phase_high; + uint32_t system__intermeasurement_period; + uint8_t system__fractional_enable; +} VL53LX_timing_config_t; + +typedef struct { + uint8_t system__grouped_parameter_hold_0; + uint16_t system__thresh_high; + uint16_t system__thresh_low; + uint8_t system__enable_xtalk_per_quadrant; + uint8_t system__seed_config; + uint8_t sd_config__woi_sd0; + uint8_t sd_config__woi_sd1; + uint8_t sd_config__initial_phase_sd0; + uint8_t sd_config__initial_phase_sd1; + uint8_t system__grouped_parameter_hold_1; + uint8_t sd_config__first_order_select; + uint8_t sd_config__quantifier; + uint8_t roi_config__user_roi_centre_spad; + uint8_t roi_config__user_roi_requested_global_xy_size; + uint8_t system__sequence_config; + uint8_t system__grouped_parameter_hold; +} VL53LX_dynamic_config_t; + +typedef struct { + uint8_t power_management__go1_power_force; + uint8_t system__stream_count_ctrl; + uint8_t firmware__enable; + uint8_t system__interrupt_clear; + uint8_t system__mode_start; +} VL53LX_system_control_t; + +typedef struct { + uint8_t result__interrupt_status; + uint8_t result__range_status; + uint8_t result__report_status; + uint8_t result__stream_count; + uint16_t result__dss_actual_effective_spads_sd0; + uint16_t result__peak_signal_count_rate_mcps_sd0; + uint16_t result__ambient_count_rate_mcps_sd0; + uint16_t result__sigma_sd0; + uint16_t result__phase_sd0; + uint16_t result__final_crosstalk_corrected_range_mm_sd0; + uint16_t result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0; + uint16_t result__mm_inner_actual_effective_spads_sd0; + uint16_t result__mm_outer_actual_effective_spads_sd0; + uint16_t result__avg_signal_count_rate_mcps_sd0; + uint16_t result__dss_actual_effective_spads_sd1; + uint16_t result__peak_signal_count_rate_mcps_sd1; + uint16_t result__ambient_count_rate_mcps_sd1; + uint16_t result__sigma_sd1; + uint16_t result__phase_sd1; + uint16_t result__final_crosstalk_corrected_range_mm_sd1; + uint16_t result__spare_0_sd1; + uint16_t result__spare_1_sd1; + uint16_t result__spare_2_sd1; + uint8_t result__spare_3_sd1; + uint8_t result__thresh_info; +} VL53LX_system_results_t; + +typedef struct { + uint8_t identification__model_id; + uint8_t identification__module_type; + uint8_t identification__revision_id; + uint16_t identification__module_id; + uint8_t ana_config__fast_osc__trim_max; + uint8_t ana_config__fast_osc__freq_set; + uint8_t ana_config__vcsel_trim; + uint8_t ana_config__vcsel_selion; + uint8_t ana_config__vcsel_selion_max; + uint8_t protected_laser_safety__lock_bit; + uint8_t laser_safety__key; + uint8_t laser_safety__key_ro; + uint8_t laser_safety__clip; + uint8_t laser_safety__mult; + uint8_t global_config__spad_enables_rtn_0; + uint8_t global_config__spad_enables_rtn_1; + uint8_t global_config__spad_enables_rtn_2; + uint8_t global_config__spad_enables_rtn_3; + uint8_t global_config__spad_enables_rtn_4; + uint8_t global_config__spad_enables_rtn_5; + uint8_t global_config__spad_enables_rtn_6; + uint8_t global_config__spad_enables_rtn_7; + uint8_t global_config__spad_enables_rtn_8; + uint8_t global_config__spad_enables_rtn_9; + uint8_t global_config__spad_enables_rtn_10; + uint8_t global_config__spad_enables_rtn_11; + uint8_t global_config__spad_enables_rtn_12; + uint8_t global_config__spad_enables_rtn_13; + uint8_t global_config__spad_enables_rtn_14; + uint8_t global_config__spad_enables_rtn_15; + uint8_t global_config__spad_enables_rtn_16; + uint8_t global_config__spad_enables_rtn_17; + uint8_t global_config__spad_enables_rtn_18; + uint8_t global_config__spad_enables_rtn_19; + uint8_t global_config__spad_enables_rtn_20; + uint8_t global_config__spad_enables_rtn_21; + uint8_t global_config__spad_enables_rtn_22; + uint8_t global_config__spad_enables_rtn_23; + uint8_t global_config__spad_enables_rtn_24; + uint8_t global_config__spad_enables_rtn_25; + uint8_t global_config__spad_enables_rtn_26; + uint8_t global_config__spad_enables_rtn_27; + uint8_t global_config__spad_enables_rtn_28; + uint8_t global_config__spad_enables_rtn_29; + uint8_t global_config__spad_enables_rtn_30; + uint8_t global_config__spad_enables_rtn_31; + uint8_t roi_config__mode_roi_centre_spad; + uint8_t roi_config__mode_roi_xy_size; +} VL53LX_nvm_copy_data_t; + +typedef struct { + VL53LX_DeviceState cfg_device_state; + VL53LX_DeviceState rd_device_state; + uint8_t zone_id; + uint32_t time_stamp; + uint8_t VL53LX_p_019; + uint8_t VL53LX_p_020; + uint8_t VL53LX_p_021; + uint8_t number_of_ambient_bins; + uint8_t bin_seq[VL53LX_MAX_BIN_SEQUENCE_LENGTH]; + uint8_t bin_rep[VL53LX_MAX_BIN_SEQUENCE_LENGTH]; + int32_t bin_data[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint8_t result__interrupt_status; + uint8_t result__range_status; + uint8_t result__report_status; + uint8_t result__stream_count; + uint16_t result__dss_actual_effective_spads; + uint16_t phasecal_result__reference_phase; + uint8_t phasecal_result__vcsel_start; + uint8_t cal_config__vcsel_start; + uint16_t vcsel_width; + uint8_t VL53LX_p_005; + uint16_t VL53LX_p_015; + uint32_t total_periods_elapsed; + uint32_t peak_duration_us; + uint32_t woi_duration_us; + int32_t min_bin_value; + int32_t max_bin_value; + uint16_t zero_distance_phase; + uint8_t number_of_ambient_samples; + int32_t ambient_events_sum; + int32_t VL53LX_p_028; + uint8_t roi_config__user_roi_centre_spad; + uint8_t roi_config__user_roi_requested_global_xy_size; +} VL53LX_histogram_bin_data_t; + +typedef struct { + uint8_t zone_id; + uint32_t time_stamp; + uint8_t VL53LX_p_019; + uint8_t VL53LX_p_020; + uint8_t VL53LX_p_021; + uint32_t bin_data[VL53LX_XTALK_HISTO_BINS]; + uint16_t phasecal_result__reference_phase; + uint8_t phasecal_result__vcsel_start; + uint8_t cal_config__vcsel_start; + uint16_t vcsel_width; + uint16_t VL53LX_p_015; + uint16_t zero_distance_phase; +} VL53LX_xtalk_histogram_shape_t; + +typedef struct { + VL53LX_xtalk_histogram_shape_t xtalk_shape; + VL53LX_histogram_bin_data_t xtalk_hist_removed; +} VL53LX_xtalk_histogram_data_t; + +typedef struct { + uint8_t no_of_samples; + uint32_t rate_per_spad_kcps_sum; + uint32_t rate_per_spad_kcps_avg; + int32_t signal_total_events_sum; + int32_t signal_total_events_avg; + uint32_t sigma_mm_sum; + uint32_t sigma_mm_avg; + uint32_t median_phase_sum; + uint32_t median_phase_avg; +} VL53LX_xtalk_range_data_t; + +typedef struct { + VL53LX_Error cal_status; + uint8_t num_of_samples_status; + uint8_t zero_samples_status; + uint8_t max_sigma_status; + uint8_t max_results; + uint8_t active_results; + VL53LX_xtalk_range_data_t VL53LX_p_003[VL53LX_MAX_XTALK_RANGE_RESULTS]; + VL53LX_histogram_bin_data_t central_histogram_sum; + VL53LX_histogram_bin_data_t central_histogram_avg; + uint8_t central_histogram__window_start; + uint8_t central_histogram__window_end; + VL53LX_histogram_bin_data_t histogram_avg_1[VL53LX_MAX_XTALK_RANGE_RESULT= S]; + VL53LX_histogram_bin_data_t histogram_avg_2[VL53LX_MAX_XTALK_RANGE_RESULT= S]; + VL53LX_histogram_bin_data_t xtalk_avg[VL53LX_MAX_XTALK_RANGE_RESULTS]; +} VL53LX_xtalk_range_results_t; + +typedef struct { + uint32_t algo__crosstalk_compensation_plane_offset_kcps; + int16_t algo__crosstalk_compensation_x_plane_gradient_kcps; + int16_t algo__crosstalk_compensation_y_plane_gradient_kcps; + uint32_t algo__xtalk_cpo_HistoMerge_kcps[VL53LX_BIN_REC_SIZE]; +} VL53LX_xtalk_calibration_results_t; + +typedef struct { + uint32_t sample_count; + uint32_t pll_period_mm; + uint32_t peak_duration_us_sum; + uint32_t effective_spad_count_sum; + uint32_t zero_distance_phase_sum; + uint32_t zero_distance_phase_avg; + int32_t event_scaler_sum; + int32_t event_scaler_avg; + int32_t signal_events_sum; + uint32_t xtalk_rate_kcps_per_spad; + int32_t xtalk_start_phase; + int32_t xtalk_end_phase; + int32_t xtalk_width_phase; + int32_t target_start_phase; + int32_t target_end_phase; + int32_t target_width_phase; + int32_t effective_width; + int32_t event_scaler; + uint8_t VL53LX_p_012; + uint8_t VL53LX_p_013; + uint8_t target_start; + int32_t max_shape_value; + int32_t bin_data_sums[VL53LX_XTALK_HISTO_BINS]; +} VL53LX_hist_xtalk_extract_data_t; + +typedef struct { + uint8_t preset_mode; + uint8_t dss_config__roi_mode_control; + uint16_t dss_config__manual_effective_spads_select; + uint8_t no_of_samples; + uint32_t effective_spads; + uint32_t peak_rate_mcps; + uint32_t VL53LX_p_002; + int32_t median_range_mm; + int32_t range_mm_offset; +} VL53LX_offset_range_data_t; + +typedef struct { + int16_t cal_distance_mm; + uint16_t cal_reflectance_pc; + VL53LX_Error cal_status; + uint8_t cal_report; + uint8_t max_results; + uint8_t active_results; + VL53LX_offset_range_data_t VL53LX_p_003[VL53LX_MAX_OFFSET_RANGE_RESULTS]; +} VL53LX_offset_range_results_t; + +typedef struct { + uint32_t result_core__ambient_window_events_sd0; + uint32_t result_core__ranging_total_events_sd0; + int32_t result_core__signal_total_events_sd0; + uint32_t result_core__total_periods_elapsed_sd0; + uint32_t result_core__ambient_window_events_sd1; + uint32_t result_core__ranging_total_events_sd1; + int32_t result_core__signal_total_events_sd1; + uint32_t result_core__total_periods_elapsed_sd1; + uint8_t result_core__spare_0; +} VL53LX_core_results_t; + +typedef struct { + + uint16_t result__actual_effective_rtn_spads; + uint8_t ref_spad_array__num_requested_ref_spads; + uint8_t ref_spad_array__ref_location; + uint16_t result__peak_signal_count_rate_rtn_mcps; + uint16_t result__ambient_count_rate_rtn_mcps; + uint16_t result__peak_signal_count_rate_ref_mcps; + uint16_t result__ambient_count_rate_ref_mcps; + uint16_t measured_distance_mm; + uint16_t measured_distance_stdev_mm; +} VL53LX_decoded_nvm_fmt_range_data_t; + +typedef struct { + uint16_t phasecal_result__reference_phase; + uint8_t phasecal_result__vcsel_start; + uint8_t ref_spad_char_result__num_actual_ref_spads; + uint8_t ref_spad_char_result__ref_location; + uint8_t vhv_result__coldboot_status; + uint8_t vhv_result__search_result; + uint8_t vhv_result__latest_setting; + uint16_t result__osc_calibrate_val; + uint8_t ana_config__powerdown_go1; + uint8_t ana_config__ref_bg_ctrl; + uint8_t ana_config__regdvdd1v2_ctrl; + uint8_t ana_config__osc_slow_ctrl; + uint8_t test_mode__status; + uint8_t firmware__system_status; + uint8_t firmware__mode_status; + uint8_t firmware__secondary_mode_status; + uint16_t firmware__cal_repeat_rate_counter; + uint16_t gph__system__thresh_high; + uint16_t gph__system__thresh_low; + uint8_t gph__system__enable_xtalk_per_quadrant; + uint8_t gph__spare_0; + uint8_t gph__sd_config__woi_sd0; + uint8_t gph__sd_config__woi_sd1; + uint8_t gph__sd_config__initial_phase_sd0; + uint8_t gph__sd_config__initial_phase_sd1; + uint8_t gph__sd_config__first_order_select; + uint8_t gph__sd_config__quantifier; + uint8_t gph__roi_config__user_roi_centre_spad; + uint8_t gph__roi_config__user_roi_requested_global_xy_size; + uint8_t gph__system__sequence_config; + uint8_t gph__gph_id; + uint8_t system__interrupt_set; + uint8_t interrupt_manager__enables; + uint8_t interrupt_manager__clear; + uint8_t interrupt_manager__status; + uint8_t mcu_to_host_bank__wr_access_en; + uint8_t power_management__go1_reset_status; + uint8_t pad_startup_mode__value_ro; + uint8_t pad_startup_mode__value_ctrl; + uint32_t pll_period_us; + uint32_t interrupt_scheduler__data_out; + uint8_t nvm_bist__complete; + uint8_t nvm_bist__status; +} VL53LX_debug_results_t; + +typedef struct { + uint8_t smudge_corr_enabled; + uint8_t smudge_corr_apply_enabled; + uint8_t smudge_corr_single_apply; + uint16_t smudge_margin; + uint32_t noise_margin; + uint32_t user_xtalk_offset_limit; + uint8_t user_xtalk_offset_limit_hi; + uint32_t sample_limit; + uint32_t single_xtalk_delta; + uint32_t averaged_xtalk_delta; + uint32_t smudge_corr_clip_limit; + uint32_t smudge_corr_ambient_threshold; + uint8_t scaler_calc_method; + int16_t x_gradient_scaler; + int16_t y_gradient_scaler; + uint8_t user_scaler_set; + uint32_t nodetect_ambient_threshold; + uint32_t nodetect_sample_limit; + uint32_t nodetect_xtalk_offset; + uint16_t nodetect_min_range_mm; + uint32_t max_smudge_factor; +} VL53LX_smudge_corrector_config_t; + +typedef struct { + uint32_t current_samples; + uint32_t required_samples; + uint64_t accumulator; + uint32_t nodetect_counter; +} VL53LX_smudge_corrector_internals_t; + +typedef struct { + uint8_t vhv_loop_bound; + uint8_t is_low_power_auto_mode; + uint8_t low_power_auto_range_count; + uint8_t saved_interrupt_config; + uint8_t saved_vhv_init; + uint8_t saved_vhv_timeout; + uint8_t first_run_phasecal_result; + uint32_t dss__total_rate_per_spad_mcps; + uint16_t dss__required_spads; +} VL53LX_low_power_auto_data_t; + +typedef struct { + int16_t short_a_offset_mm; + int16_t short_b_offset_mm; + int16_t medium_a_offset_mm; + int16_t medium_b_offset_mm; + int16_t long_a_offset_mm; + int16_t long_b_offset_mm; +} VL53LX_per_vcsel_period_offset_cal_data_t; + +typedef struct { + uint8_t wait_method; + VL53LX_DevicePresetModes preset_mode; + VL53LX_DeviceZonePreset zone_preset; + VL53LX_DeviceMeasurementModes measurement_mode; + VL53LX_OffsetCalibrationMode offset_calibration_mode; + VL53LX_OffsetCorrectionMode offset_correction_mode; + VL53LX_DeviceDmaxMode dmax_mode; + uint32_t phasecal_config_timeout_us; + uint32_t mm_config_timeout_us; + uint32_t range_config_timeout_us; + uint32_t inter_measurement_period_ms; + uint16_t dss_config__target_total_rate_mcps; + uint32_t fw_ready_poll_duration_ms; + uint8_t fw_ready; + uint8_t debug_mode; + VL53LX_ll_version_t version; + VL53LX_ll_driver_state_t ll_state; + VL53LX_GPIO_interrupt_config_t gpio_interrupt_config; + VL53LX_customer_nvm_managed_t customer; + VL53LX_cal_peak_rate_map_t cal_peak_rate_map; + VL53LX_additional_offset_cal_data_t add_off_cal_data; + VL53LX_dmax_calibration_data_t fmt_dmax_cal; + VL53LX_dmax_calibration_data_t cust_dmax_cal; + VL53LX_gain_calibration_data_t gain_cal; + VL53LX_user_zone_t mm_roi; + VL53LX_optical_centre_t optical_centre; + VL53LX_zone_config_t zone_cfg; + VL53LX_tuning_parm_storage_t tuning_parms; + uint8_t rtn_good_spads[VL53LX_RTN_SPAD_BUFFER_SIZE]; + VL53LX_refspadchar_config_t refspadchar; + VL53LX_ssc_config_t ssc_cfg; + VL53LX_hist_post_process_config_t histpostprocess; + VL53LX_hist_gen3_dmax_config_t dmax_cfg; + VL53LX_xtalkextract_config_t xtalk_extract_cfg; + VL53LX_xtalk_config_t xtalk_cfg; + VL53LX_offsetcal_config_t offsetcal_cfg; + VL53LX_zonecal_config_t zonecal_cfg; + VL53LX_static_nvm_managed_t stat_nvm; + VL53LX_histogram_config_t hist_cfg; + VL53LX_static_config_t stat_cfg; + VL53LX_general_config_t gen_cfg; + VL53LX_timing_config_t tim_cfg; + VL53LX_dynamic_config_t dyn_cfg; + VL53LX_system_control_t sys_ctrl; + VL53LX_system_results_t sys_results; + VL53LX_nvm_copy_data_t nvm_copy_data; + VL53LX_histogram_bin_data_t hist_data; + VL53LX_histogram_bin_data_t hist_xtalk; + VL53LX_xtalk_histogram_data_t xtalk_shapes; + VL53LX_xtalk_range_results_t xtalk_results; + VL53LX_xtalk_calibration_results_t xtalk_cal; + VL53LX_hist_xtalk_extract_data_t xtalk_extract; + VL53LX_offset_range_results_t offset_results; + VL53LX_core_results_t core_results; + VL53LX_debug_results_t dbg_results; + VL53LX_smudge_corrector_config_t smudge_correct_config; + VL53LX_smudge_corrector_internals_t smudge_corrector_internals; + VL53LX_low_power_auto_data_t low_power_auto_data; + uint8_t wArea1[1536]; + uint8_t wArea2[512]; + VL53LX_per_vcsel_period_offset_cal_data_t per_vcsel_cal_data; + uint8_t bin_rec_pos; + uint8_t pos_before_next_recom; + int32_t multi_bins_rec[VL53LX_BIN_REC_SIZE][VL53LX_TIMING_CONF_A_B_SIZE]= [VL53LX_HISTOGRAM_BUFFER_SIZE]; + int16_t PreviousRangeMilliMeter[VL53LX_MAX_RANGE_RESULTS]; + uint8_t PreviousRangeStatus[VL53LX_MAX_RANGE_RESULTS]; + uint8_t PreviousExtendedRange[VL53LX_MAX_RANGE_RESULTS]; + uint8_t PreviousRangeActiveResults; + uint8_t PreviousStreamCount; +} VL53LX_LLDriverData_t; + +typedef struct { + uint8_t expected_stream_count; + uint8_t expected_gph_id; + uint8_t dss_mode; + uint16_t dss_requested_effective_spad_count; + uint8_t seed_cfg; + uint8_t initial_phase_seed; + uint8_t roi_config__user_roi_centre_spad; + uint8_t roi_config__user_roi_requested_global_xy_size; +} VL53LX_zone_private_dyn_cfg_t; + +typedef struct { + uint8_t max_zones; + uint8_t active_zones; + VL53LX_zone_private_dyn_cfg_t VL53LX_p_003[VL53LX_MAX_USER_ZONES]; +} VL53LX_zone_private_dyn_cfgs_t; + +typedef struct { + uint8_t range_id; + uint32_t time_stamp; + uint8_t VL53LX_p_012; + uint8_t VL53LX_p_019; + uint8_t VL53LX_p_023; + uint8_t VL53LX_p_024; + uint8_t VL53LX_p_013; + uint8_t VL53LX_p_025; + uint16_t width; + uint8_t VL53LX_p_029; + uint16_t fast_osc_frequency; + uint16_t zero_distance_phase; + uint16_t VL53LX_p_004; + uint32_t total_periods_elapsed; + uint32_t peak_duration_us; + uint32_t woi_duration_us; + uint32_t VL53LX_p_016; + uint32_t VL53LX_p_017; + int32_t VL53LX_p_010; + uint16_t peak_signal_count_rate_mcps; + uint16_t avg_signal_count_rate_mcps; + uint16_t ambient_count_rate_mcps; + uint16_t total_rate_per_spad_mcps; + uint32_t VL53LX_p_009; + uint16_t VL53LX_p_002; + uint16_t VL53LX_p_026; + uint16_t VL53LX_p_011; + uint16_t VL53LX_p_027; + int16_t min_range_mm; + int16_t median_range_mm; + int16_t max_range_mm; + uint8_t range_status; +} VL53LX_range_data_t; + +typedef struct { + uint8_t smudge_corr_valid; + uint8_t smudge_corr_clipped; + uint8_t single_xtalk_delta_flag; + uint8_t averaged_xtalk_delta_flag; + uint8_t sample_limit_exceeded_flag; + uint8_t gradient_zero_flag; + uint8_t new_xtalk_applied_flag; + uint32_t algo__crosstalk_compensation_plane_offset_kcps; + int16_t algo__crosstalk_compensation_x_plane_gradient_kcps; + int16_t algo__crosstalk_compensation_y_plane_gradient_kcps; +} VL53LX_smudge_corrector_data_t; + +typedef struct { + VL53LX_DeviceState cfg_device_state; + VL53LX_DeviceState rd_device_state; + uint8_t zone_id; + uint8_t stream_count; + int16_t VL53LX_p_022[VL53LX_MAX_AMBIENT_DMAX_VALUES]; + int16_t wrap_dmax_mm; + uint8_t device_status; + uint8_t max_results; + uint8_t active_results; + VL53LX_range_data_t VL53LX_p_003[VL53LX_MAX_RANGE_RESULTS]; + VL53LX_range_data_t xmonitor; + VL53LX_smudge_corrector_data_t smudge_corrector_data; +} VL53LX_range_results_t; + +typedef struct { + uint8_t max_zones; + uint8_t active_zones; + VL53LX_zone_objects_t VL53LX_p_003[VL53LX_MAX_USER_ZONES]; +} VL53LX_zone_results_t; + +typedef struct { + VL53LX_DeviceState rd_device_state; + uint8_t number_of_ambient_bins; + uint16_t result__dss_actual_effective_spads; + uint8_t VL53LX_p_005; + uint32_t total_periods_elapsed; + int32_t ambient_events_sum; +} VL53LX_zone_hist_info_t; + +typedef struct { + uint8_t max_zones; + uint8_t active_zones; + VL53LX_zone_hist_info_t VL53LX_p_003[VL53LX_MAX_USER_ZONES]; +} VL53LX_zone_histograms_t; + +typedef struct { + uint32_t no_of_samples; + uint32_t effective_spads; + uint32_t peak_rate_mcps; + uint32_t VL53LX_p_011; + uint32_t VL53LX_p_002; + int32_t median_range_mm; + int32_t range_mm_offset; +} VL53LX_zone_calibration_data_t; + +typedef struct { + uint32_t struct_version; + VL53LX_DevicePresetModes preset_mode; + VL53LX_DeviceZonePreset zone_preset; + int16_t cal_distance_mm; + uint16_t cal_reflectance_pc; + uint16_t phasecal_result__reference_phase; + uint16_t zero_distance_phase; + VL53LX_Error cal_status; + uint8_t max_zones; + uint8_t active_zones; + VL53LX_zone_calibration_data_t VL53LX_p_003[VL53LX_MAX_USER_ZONES]; +} VL53LX_zone_calibration_results_t; + +typedef struct { + VL53LX_range_results_t range_results; + VL53LX_zone_private_dyn_cfgs_t zone_dyn_cfgs; + VL53LX_zone_results_t zone_results; + VL53LX_zone_histograms_t zone_hists; + VL53LX_zone_calibration_results_t zone_cal; +} VL53LX_LLDriverResults_t; + +typedef struct { + VL53LX_DistanceModes DistanceMode; + uint32_t MeasurementTimingBudgetMicroSeconds; +} VL53LX_DeviceParameters_t; + +typedef struct { + VL53LX_LLDriverData_t LLData; + VL53LX_LLDriverResults_t llresults; + VL53LX_DeviceParameters_t CurrentParameters; +} VL53LX_DevData_t; + +typedef struct { + uint8_t global_config__spad_enables_ref_0; + uint8_t global_config__spad_enables_ref_1; + uint8_t global_config__spad_enables_ref_2; + uint8_t global_config__spad_enables_ref_3; + uint8_t global_config__spad_enables_ref_4; + uint8_t global_config__spad_enables_ref_5; + uint8_t global_config__ref_en_start_select; + uint8_t ref_spad_man__num_requested_ref_spads; + uint8_t ref_spad_man__ref_location; + uint32_t algo__crosstalk_compensation_plane_offset_kcps; + int16_t algo__crosstalk_compensation_x_plane_gradient_kcps; + int16_t algo__crosstalk_compensation_y_plane_gradient_kcps; + uint16_t ref_spad_char__total_rate_target_mcps; + int16_t algo__part_to_part_range_offset_mm; + int16_t mm_config__inner_offset_mm; + int16_t mm_config__outer_offset_mm; +} VL53LX_CustomerNvmManaged_t; + +typedef struct { + uint32_t struct_version; + VL53LX_CustomerNvmManaged_t customer; + VL53LX_additional_offset_cal_data_t add_off_cal_data; + VL53LX_optical_centre_t optical_centre; + VL53LX_xtalk_histogram_data_t xtalkhisto; + VL53LX_gain_calibration_data_t gain_cal; + VL53LX_cal_peak_rate_map_t cal_peak_rate_map; + VL53LX_per_vcsel_period_offset_cal_data_t per_vcsel_cal_data; + uint32_t algo__xtalk_cpo_HistoMerge_kcps[VL53LX_BIN_REC_SIZE]; +} VL53LX_CalibrationData_t; + +struct stmvl53lx_ioctl_calibration_data_t { + int32_t is_read; + VL53LX_CalibrationData_t data; +}; + +struct stmvl53lx_ioctl_perform_calibration_t { + uint32_t calibration_type; + uint32_t param1; + uint32_t param2; + uint32_t param3; +}; + +typedef struct { + uint8_t ProductType; + uint8_t ProductRevisionMajor; + uint8_t ProductRevisionMinor; +} VL53LX_DeviceInfo_t; + +typedef struct { + int16_t RangeMaxMilliMeter; + int16_t RangeMinMilliMeter; + FixPoint1616_t SignalRateRtnMegaCps; + FixPoint1616_t AmbientRateRtnMegaCps; + FixPoint1616_t SigmaMilliMeter; + int16_t RangeMilliMeter; + uint8_t RangeStatus; + uint8_t ExtendedRange; +} VL53LX_TargetRangeData_t; + +typedef struct { + uint32_t TimeStamp; + uint8_t StreamCount; + uint8_t NumberOfObjectsFound; + VL53LX_TargetRangeData_t RangeData[VL53LX_MAX_RANGE_RESULTS]; + uint8_t HasXtalkValueChanged; + uint16_t EffectiveSpadRtnCount; +} VL53LX_MultiRangingData_t; + +typedef struct { + VL53LX_DevicePresetModes preset_mode; + VL53LX_DeviceZonePreset zone_preset; + VL53LX_DeviceMeasurementModes measurement_mode; + VL53LX_OffsetCalibrationMode offset_calibration_mode; + VL53LX_OffsetCorrectionMode offset_correction_mode; + VL53LX_DeviceDmaxMode dmax_mode; + uint32_t phasecal_config_timeout_us; + uint32_t mm_config_timeout_us; + uint32_t range_config_timeout_us; + uint32_t inter_measurement_period_ms; + uint16_t dss_config__target_total_rate_mcps; + VL53LX_histogram_bin_data_t VL53LX_p_006; +} VL53LX_additional_data_t; + +typedef VL53LX_additional_data_t VL53LX_AdditionalData_t; + +struct stmvl53lx_data_with_additional { + VL53LX_MultiRangingData_t data; + VL53LX_AdditionalData_t additional_data; +}; + +typedef struct { + + uint32_t struct_version; + VL53LX_customer_nvm_managed_t customer; + VL53LX_dmax_calibration_data_t fmt_dmax_cal; + VL53LX_dmax_calibration_data_t cust_dmax_cal; + VL53LX_additional_offset_cal_data_t add_off_cal_data; + VL53LX_optical_centre_t optical_centre; + VL53LX_xtalk_histogram_data_t xtalkhisto; + VL53LX_gain_calibration_data_t gain_cal; + VL53LX_cal_peak_rate_map_t cal_peak_rate_map; + VL53LX_per_vcsel_period_offset_cal_data_t per_vcsel_cal_data; +} VL53LX_calibration_data_t; + +typedef struct { + uint8_t VL53LX_p_019; + uint8_t VL53LX_p_020; + uint8_t VL53LX_p_021; + uint8_t VL53LX_p_029; + int32_t VL53LX_p_016; + int32_t VL53LX_p_043[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_068[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint8_t VL53LX_p_040[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_018[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint16_t VL53LX_p_014[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint16_t VL53LX_p_008[VL53LX_HISTOGRAM_BUFFER_SIZE]; + +} VL53LX_hist_gen1_algo_private_data_t; + +typedef struct { + uint8_t VL53LX_p_019; + uint8_t VL53LX_p_020; + uint8_t VL53LX_p_021; + uint16_t VL53LX_p_015; + uint8_t VL53LX_p_005; + uint8_t VL53LX_p_029; + int32_t VL53LX_p_028; + int32_t VL53LX_p_016; + int32_t VL53LX_p_007[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_032[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_001[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_018[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_055[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_053[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_054[VL53LX_HISTOGRAM_BUFFER_SIZE]; +} VL53LX_hist_gen2_algo_filtered_data_t; + +typedef struct { + uint8_t VL53LX_p_019; + uint8_t VL53LX_p_020; + uint8_t VL53LX_p_021; + int32_t VL53LX_p_031; + uint8_t VL53LX_p_069[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint8_t VL53LX_p_070[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint32_t VL53LX_p_014[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint16_t VL53LX_p_008[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint8_t VL53LX_p_040[VL53LX_HISTOGRAM_BUFFER_SIZE]; +} VL53LX_hist_gen2_algo_detection_data_t; + +typedef struct { + uint8_t VL53LX_p_012; + uint8_t VL53LX_p_019; + uint8_t VL53LX_p_023; + uint8_t VL53LX_p_024; + uint8_t VL53LX_p_013; + uint8_t VL53LX_p_025; + uint8_t VL53LX_p_051; + int32_t VL53LX_p_016; + int32_t VL53LX_p_017; + int32_t VL53LX_p_010; + uint32_t VL53LX_p_026; + uint32_t VL53LX_p_011; + uint32_t VL53LX_p_027; + uint16_t VL53LX_p_002; +} VL53LX_hist_pulse_data_t; + +typedef struct { + uint8_t VL53LX_p_019; + uint8_t VL53LX_p_020; + uint8_t VL53LX_p_021; + uint8_t VL53LX_p_030; + uint8_t VL53LX_p_039; + int32_t VL53LX_p_028; + int32_t VL53LX_p_031; + uint8_t VL53LX_p_040[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint8_t VL53LX_p_041[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint8_t VL53LX_p_042[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_052[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_043[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_018[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint8_t VL53LX_p_044; + uint8_t VL53LX_p_045; + uint8_t VL53LX_p_046; + VL53LX_hist_pulse_data_t VL53LX_p_003[VL53LX_D_001]; + VL53LX_histogram_bin_data_t VL53LX_p_006; + VL53LX_histogram_bin_data_t VL53LX_p_047; + VL53LX_histogram_bin_data_t VL53LX_p_048; + VL53LX_histogram_bin_data_t VL53LX_p_049; + VL53LX_histogram_bin_data_t VL53LX_p_050; +} VL53LX_hist_gen3_algo_private_data_t; + +typedef struct { + uint8_t VL53LX_p_019; + uint8_t VL53LX_p_020; + uint8_t VL53LX_p_021; + int32_t VL53LX_p_007[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_032[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_001[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_053[VL53LX_HISTOGRAM_BUFFER_SIZE]; + int32_t VL53LX_p_054[VL53LX_HISTOGRAM_BUFFER_SIZE]; + uint8_t VL53LX_p_040[VL53LX_HISTOGRAM_BUFFER_SIZE]; +} VL53LX_hist_gen4_algo_filtered_data_t; + +struct st_timeval { + time64_t tv_sec; + long tv_usec; +}; + +struct stmvl53lx_data { + int id; + char name[64]; + VL53LX_DevData_t stdev; + void *client_object; + bool is_device_remove; + struct mutex work_mutex; + struct delayed_work dwork; + struct input_dev *input_dev_ps; + struct miscdevice miscdev; + int is_first_irq; + int is_first_start_done; + int poll_mode; + int poll_delay_ms; + int enable_sensor; + struct st_timeval start_tv; + int enable_debug; + bool allow_hidden_start_stop; + int32_t timing_budget; + int distance_mode; + int crosstalk_enable; + int output_mode; + bool force_device_on_en; + VL53LX_Error last_error; + int offset_correction_mode; + int smudge_correction_mode; + FixPoint1616_t optical_offset_x; + FixPoint1616_t optical_offset_y; + bool is_xtalk_value_changed; + bool is_calibrating; + struct range_t { + uint32_t cnt; + uint32_t intr; + int poll_cnt; + uint32_t err_cnt; + uint32_t err_tot; + struct st_timeval start_tv; + struct st_timeval comp_tv; + VL53LX_MultiRangingData_t multi_range_data; + VL53LX_MultiRangingData_t tmp_range_data; + VL53LX_AdditionalData_t additional_data; + } meas; + uint32_t flushCount; + int flush_todo_counter; + struct list_head simple_data_reader_list; + struct list_head mz_data_reader_list; + wait_queue_head_t waiter_for_data; + bool is_data_valid; + bool is_delay_allowed; + int reset_state; + VL53LX_UserRoi_t roi_cfg; +}; + +struct i2c_data { + struct i2c_client *client; + struct stmvl53lx_data *vl53lx_data; + struct kref ref; + struct regulator *vdd; + int pwren_gpio; + int xsdn_gpio; + int intr_gpio; + int boot_reg; + struct i2d_data_flags_t { + unsigned pwr_owned:1; + unsigned xsdn_owned:1; + unsigned intr_owned:1; + unsigned intr_started:1; + } io_flag; + int irq; + struct msgtctrl_t { + unsigned unhandled_irq_vec:1; + } msg_flag; +}; + +struct stmvl53lx_waiters { + struct list_head list; + pid_t pid; +}; + +struct stmvl53lx_data *stmvl53lx_dev_table[STMVL53LX_CFG_MAX_DEV]; + +struct stmvl53lx_module_fn_t { + int (*init)(void); + void (*deinit)(void *data); + int (*power_up)(void *data); + int (*power_down)(void *data); + int (*reset_release)(void *data); + int (*reset_hold)(void *data); + int (*start_intr)(void *object, int *poll_mode); + void (*clean_up)(void); + void *(*get)(void *object); + void (*put)(void *object); +}; + +static int32_t BDTable[VL53LX_TUNING_MAX_TUNABLE_KEY] =3D { + TUNING_VERSION, + TUNING_PROXY_MIN, + TUNING_SINGLE_TARGET_XTALK_TARGET_DISTANCE_MM, + TUNING_SINGLE_TARGET_XTALK_SAMPLE_NUMBER, + TUNING_MIN_AMBIENT_DMAX_VALID, + TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER, + TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM, + TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT, + TUNING_XTALK_FULL_ROI_BIN_SUM_MARGIN, + TUNING_XTALK_FULL_ROI_DEFAULT_OFFSET, + TUNING_ZERO_DISTANCE_OFFSET_NON_LINEAR_FACTOR_DEFAULT +}; + +static struct i2c_client *stm_test_i2c_client; + +static const int tunings[][2] =3D { +}; + +int stmvl53lx_enable_debug =3D 1; + +static int force_device; +static int adapter_nb =3D -1; +static int xsdn_gpio_nb =3D -1; +static int pwren_gpio_nb =3D -1; +static int intr_gpio_nb =3D -1; +static int i2c_addr_nb =3D STMVL53LX_SLAVE_ADDR; + +static bool force_device_on_en_default =3D true; + +module_param(force_device_on_en_default, bool, 0444); +MODULE_PARM_DESC(force_device_on_en_default, "select whether force_device_= on_en is true or false by default"); + +module_param(force_device, int, 0000); +MODULE_PARM_DESC(force_device, "force device insertion at module init"); + +module_param(adapter_nb, int, 0000); +MODULE_PARM_DESC(adapter_nb, "i2c adapter to use"); + +module_param(i2c_addr_nb, int, 0000); +MODULE_PARM_DESC(i2c_addr_nb, "desired i2c device address on adapter "); + +module_param(xsdn_gpio_nb, int, 0000); +MODULE_PARM_DESC(xsdn_gpio_nb, "select gpio numer to use for vl53lx reset"= ); + +module_param(pwren_gpio_nb, int, 0000); +MODULE_PARM_DESC(pwren_gpio_nb, "select gpio numer to use for vl53lx power= "); + +module_param(intr_gpio_nb, int, 0000); +MODULE_PARM_DESC(intr_gpio_nb, "select gpio numer to use for vl53lx interr= upt"); +static DEFINE_MUTEX(dev_addr_change_mutex); +static DEFINE_MUTEX(dev_table_mutex); + +static struct stmvl53lx_module_fn_t stmvl53lx_module_func_tbl; +static int _ctrl_stop(struct stmvl53lx_data *data); +static int reset_hold(struct stmvl53lx_data *data); +static void stmvl53lx_insert_flush_events_lock(struct stmvl53lx_data *data= ); +VL53LX_Error VL53LX_GetCalibrationData(VL53LX_DEV Dev, VL53LX_CalibrationD= ata_t *pCalibrationData); +VL53LX_Error VL53LX_get_device_results(VL53LX_DEV Dev, VL53LX_DeviceResult= sLevel device_results_level, VL53LX_range_results_t *prange_results); +VL53LX_Error VL53LX_poll_for_range_completion(VL53LX_DEV Dev, uint32_t tim= eout_ms); +VL53LX_Error VL53LX_preset_mode_histogram_short_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg); +static VL53LX_Error SetMeasurementData(VL53LX_DEV Dev, VL53LX_range_result= s_t *presults, VL53LX_MultiRangingData_t *pMultiRangingData); +void stmvl53lx_put(void *object); +void st_gettimeofday(struct st_timeval *tv); +VL53LX_Error VL53LX_WaitUs(VL53LX_DEV pdev, int32_t wait_us); +VL53LX_Error VL53LX_WaitMs(VL53LX_DEV pdev, int32_t wait_ms); +VL53LX_Error VL53LX_WaitValueMaskEx(VL53LX_DEV pdev, uint32_t timeout_ms, = uint16_t index, uint8_t value, uint8_t mask, uint32_t poll_delay_ms); +void VL53LX_init_ll_driver_state(VL53LX_DEV Dev, VL53LX_DeviceState device= _state); +VL53LX_Error VL53LX_poll_for_boot_completion(VL53LX_DEV Dev, uint32_t time= out_ms); +VL53LX_Error VL53LX_WaitDeviceBooted(VL53LX_DEV Dev); +uint32_t VL53LX_calc_pll_period_us(uint16_t fast_osc_frequency); +uint8_t VL53LX_decode_vcsel_period(uint8_t vcsel_period_reg); +uint32_t VL53LX_calc_macro_period_us(uint16_t fast_osc_frequency, uint8_t = VL53LX_p_005); +uint32_t VL53LX_calc_timeout_us(uint32_t timeout_mclks, uint32_t macro_per= iod_us); +uint32_t VL53LX_decode_timeout(uint16_t encoded_timeout); +uint32_t VL53LX_calc_decoded_timeout_us( + uint16_t timeout_encoded, + uint32_t macro_period_us); +VL53LX_Error VL53LX_get_timeouts_us(VL53LX_DEV Dev, uint32_t *pphasecal_co= nfig_timeout_us, uint32_t *pmm_config_timeout_us, uint32_t *prange_config_t= imeout_us); +uint32_t VL53LX_calc_timeout_mclks(uint32_t timeout_us, uint32_t macro_per= iod_us); +uint16_t VL53LX_encode_timeout(uint32_t timeout_mclks); +uint16_t VL53LX_calc_encoded_timeout(uint32_t timeout_us, uint32_t macro_p= eriod_us); +VL53LX_Error VL53LX_calc_timeout_register_values(uint32_t phasecal_config_= timeout_us, uint32_t mm_config_timeout_us, uint32_t range_config_timeout_us= , uint16_t fast_osc_frequency, VL53LX_general_config_t *pgeneral, VL53LX_ti= ming_config_t *ptiming); +VL53LX_Error VL53LX_set_timeouts_us(VL53LX_DEV Dev, uint32_t phasecal_conf= ig_timeout_us, uint32_t mm_config_timeout_us, uint32_t range_config_timeout= _us); +VL53LX_Error VL53LX_SetMeasurementTimingBudgetMicroSeconds(VL53LX_DEV Dev,= uint32_t MeasurementTimingBudgetMicroSeconds); +VL53LX_Error VL53LX_i2c_encode_system_control(VL53LX_system_control_t *pda= ta, uint16_t buf_size, uint8_t *pbuffer); +VL53LX_Error VL53LX_WriteMulti(VL53LX_DEV pdev, uint16_t index, uint8_t *p= data, uint32_t count); +VL53LX_Error VL53LX_ReadMulti(VL53LX_DEV pdev, uint16_t index, uint8_t *pd= ata, uint32_t count); +VL53LX_Error VL53LX_RdByte(VL53LX_DEV pdev, uint16_t index, uint8_t *pdata= ); +VL53LX_Error VL53LX_WrByte(VL53LX_DEV pdev, uint16_t index, uint8_t data); +VL53LX_Error VL53LX_RdWord(VL53LX_DEV pdev, uint16_t index, uint16_t *pdat= a); +VL53LX_Error VL53LX_WrWord(VL53LX_DEV pdev, uint16_t index, uint16_t data); +VL53LX_Error VL53LX_WrDWord(VL53LX_DEV pdev, uint16_t index, uint32_t data= ); +VL53LX_Error VL53LX_RdDWord(VL53LX_DEV pdev, uint16_t index, uint32_t *pda= ta); +VL53LX_Error VL53LX_set_system_control(VL53LX_DEV Dev, VL53LX_system_contr= ol_t *pdata); +void V53L1_init_zone_results_structure(uint8_t active_zones, VL53LX_zone_r= esults_t *pdata); +void V53L1_init_zone_dss_configs(VL53LX_DEV Dev); +VL53LX_Error VL53LX_low_power_auto_data_stop_range(VL53LX_DEV Dev); +VL53LX_Error VL53LX_stop_range(VL53LX_DEV Dev); +VL53LX_Error VL53LX_set_powerforce_register(VL53LX_DEV Dev, uint8_t value); +VL53LX_Error VL53LX_disable_powerforce(VL53LX_DEV Dev); +VL53LX_Error VL53LX_unload_patch(VL53LX_DEV Dev); +VL53LX_Error VL53LX_StopMeasurement(VL53LX_DEV Dev); +void VL53LX_i2c_encode_uint16_t(uint16_t ip_value, uint16_t count, uint8_t= *pbuffer); +uint16_t VL53LX_i2c_decode_uint16_t(uint16_t count, uint8_t *pbuffer); +void VL53LX_i2c_encode_int16_t(int16_t ip_value, uint16_t count, uint8_t *= pbuffer); +int16_t VL53LX_i2c_decode_int16_t(uint16_t count, uint8_t *pbuffer); +uint32_t VL53LX_i2c_decode_with_mask(uint16_t count, uint8_t *pbuffer, uin= t32_t bit_mask, uint32_t down_shift, uint32_t offset); +void VL53LX_i2c_encode_int32_t(int32_t ip_value, uint16_t count, uint8_t *= pbuffer); +int32_t VL53LX_i2c_decode_int32_t(uint16_t count, uint8_t *pbuffer); +VL53LX_Error VL53LX_i2c_encode_customer_nvm_managed(VL53LX_customer_nvm_ma= naged_t *pdata, uint16_t buf_size, uint8_t *pbuffer); +VL53LX_Error VL53LX_set_customer_nvm_managed(VL53LX_DEV Dev, VL53LX_custom= er_nvm_managed_t *pdata); +VL53LX_Error VL53LX_disable_xtalk_compensation(VL53LX_DEV Dev); +uint32_t VL53LX_calc_crosstalk_plane_offset_with_margin(uint32_t plane_off= set_kcps, int16_t margin_offset_kcps); +uint16_t VL53LX_calc_range_ignore_threshold(uint32_t central_rate, int16_t= x_gradient, int16_t y_gradient, uint8_t rate_mult); +VL53LX_Error VL53LX_enable_xtalk_compensation(VL53LX_DEV Dev); +VL53LX_Error VL53LX_SetXTalkCompensationEnable(VL53LX_DEV Dev, uint8_t XTa= lkCompensationEnable); +VL53LX_Error VL53LX_get_preset_mode_timing_cfg(VL53LX_DEV Dev, VL53LX_Devi= cePresetModes device_preset_mode, uint16_t *pdss_config__target_total_rate_= mcps, uint32_t *pphasecal_config_timeout_us, uint32_t *pmm_config_timeout_u= s, uint32_t *prange_config_timeout_us); +VL53LX_Error VL53LX_preset_mode_standard_ranging( + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg); +void VL53LX_init_histogram_config_structure( + uint8_t even_bin0, + uint8_t even_bin1, + uint8_t even_bin2, + uint8_t even_bin3, + uint8_t even_bin4, + uint8_t even_bin5, + uint8_t odd_bin0, + uint8_t odd_bin1, + uint8_t odd_bin2, + uint8_t odd_bin3, + uint8_t odd_bin4, + uint8_t odd_bin5, + VL53LX_histogram_config_t *pdata); +void VL53LX_init_histogram_multizone_config_structure( + uint8_t even_bin0, + uint8_t even_bin1, + uint8_t even_bin2, + uint8_t even_bin3, + uint8_t even_bin4, + uint8_t even_bin5, + uint8_t odd_bin0, + uint8_t odd_bin1, + uint8_t odd_bin2, + uint8_t odd_bin3, + uint8_t odd_bin4, + uint8_t odd_bin5, + VL53LX_histogram_config_t *pdata); +void VL53LX_copy_hist_cfg_to_static_cfg( + VL53LX_histogram_config_t *phistogram, + VL53LX_static_config_t *pstatic, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic); +VL53LX_Error VL53LX_preset_mode_histogram_ranging( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg); +VL53LX_Error VL53LX_preset_mode_histogram_long_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg); +VL53LX_Error VL53LX_set_inter_measurement_period_ms(VL53LX_DEV Dev, uint32= _t inter_measurement_period_ms); +VL53LX_Error VL53LX_preset_mode_histogram_medium_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg); +VL53LX_Error VL53LX_set_preset_mode(VL53LX_DEV Dev, VL53LX_DevicePresetMod= es device_preset_mode, uint16_t dss_config__target_total_rate_mcps, uint32_= t phasecal_config_timeout_us, uint32_t mm_config_timeout_us, uint32_t range= _config_timeout_us, uint32_t inter_measurement_period_ms); +VL53LX_Error VL53LX_SetDistanceMode(VL53LX_DEV Dev, VL53LX_DistanceModes D= istanceMode); +VL53LX_Error VL53LX_set_offset_correction_mode(VL53LX_DEV Dev, VL53LX_Offs= etCorrectionMode offset_cor_mode); +VL53LX_Error VL53LX_SetOffsetCorrectionMode(VL53LX_DEV Dev, VL53LX_OffsetC= orrectionModes OffsetCorrectionMode); +VL53LX_Error VL53LX_dynamic_xtalk_correction_disable(VL53LX_DEV Dev); +VL53LX_Error VL53LX_dynamic_xtalk_correction_apply_disable(VL53LX_DEV Dev); +VL53LX_Error VL53LX_dynamic_xtalk_correction_single_apply_disable(VL53LX_D= EV Dev); +VL53LX_Error VL53LX_dynamic_xtalk_correction_enable(VL53LX_DEV Dev); +VL53LX_Error VL53LX_dynamic_xtalk_correction_apply_enable(VL53LX_DEV Dev); +VL53LX_Error VL53LX_dynamic_xtalk_correction_single_apply_enable(VL53LX_DE= V Dev); +VL53LX_Error VL53LX_SmudgeCorrectionEnable(VL53LX_DEV Dev, VL53LX_SmudgeCo= rrectionModes Mode); +VL53LX_Error VL53LX_init_zone_config_histogram_bins(VL53LX_zone_config_t *= pdata); +VL53LX_Error VL53LX_set_zone_config(VL53LX_DEV Dev, VL53LX_zone_config_t *= pzone_cfg); +VL53LX_Error VL53LX_SetUserROI(VL53LX_DEV Dev, VL53LX_UserRoi_t *pRoi); +VL53LX_Error VL53LX_enable_powerforce(VL53LX_DEV Dev); +VL53LX_Error VL53LX_get_tuning_parm(VL53LX_DEV Dev, VL53LX_TuningParms tun= ing_parm_key, int32_t *ptuning_parm_value); +VL53LX_Error VL53LX_load_patch(VL53LX_DEV Dev); +void VL53LX_encode_row_col(uint8_t row, uint8_t col, uint8_t *pspad_number= ); +void VL53LX_encode_zone_size(uint8_t width, uint8_t height, uint8_t *penco= ded_xy_size); +VL53LX_Error VL53LX_set_user_zone(VL53LX_DEV Dev, VL53LX_user_zone_t *puse= r_zone); +VL53LX_Error VL53LX_set_zone_dss_config(VL53LX_DEV Dev, VL53LX_zone_privat= e_dyn_cfg_t *pzone_dyn_cfg); +VL53LX_Error VL53LX_save_cfg_data(VL53LX_DEV Dev); +VL53LX_Error VL53LX_i2c_encode_static_nvm_managed(VL53LX_static_nvm_manage= d_t *pdata, uint16_t buf_size, uint8_t *pbuffer); +VL53LX_Error VL53LX_i2c_decode_static_nvm_managed(uint16_t buf_size, uint8= _t *pbuffer, VL53LX_static_nvm_managed_t *pdata); +VL53LX_Error VL53LX_i2c_encode_static_config(VL53LX_static_config_t *pdata= , uint16_t buf_size, uint8_t *pbuffer); +VL53LX_Error VL53LX_i2c_encode_general_config(VL53LX_general_config_t *pda= ta, uint16_t buf_size, uint8_t *pbuffer); +void VL53LX_i2c_encode_uint32_t(uint32_t ip_value, uint16_t count, uint8_t= *pbuffer); +uint32_t VL53LX_i2c_decode_uint32_t(uint16_t count, uint8_t *pbuffer); +VL53LX_Error VL53LX_i2c_encode_timing_config(VL53LX_timing_config_t *pdata= , uint16_t buf_size, uint8_t *pbuffer); +VL53LX_Error VL53LX_i2c_encode_dynamic_config(VL53LX_dynamic_config_t *pda= ta, uint16_t buf_size, uint8_t *pbuffer); +VL53LX_Error VL53LX_update_internal_stream_counters(VL53LX_DEV Dev, uint8_= t external_stream_count, uint8_t *pinternal_stream_count, uint8_t *pinterna= l_stream_count_val); +VL53LX_Error VL53LX_update_ll_driver_rd_state(VL53LX_DEV Dev); +VL53LX_Error VL53LX_update_ll_driver_cfg_state(VL53LX_DEV Dev); +VL53LX_Error VL53LX_init_and_start_range(VL53LX_DEV Dev, uint8_t measureme= nt_mode, VL53LX_DeviceConfigLevel device_config_level); +VL53LX_Error VL53LX_StartMeasurement(VL53LX_DEV Dev); +VL53LX_Error VL53LX_WaitMeasurementDataReady(VL53LX_DEV Dev); +VL53LX_Error VL53LX_is_new_data_ready(VL53LX_DEV Dev, uint8_t *pready); +VL53LX_Error VL53LX_GetMeasurementDataReady(VL53LX_DEV Dev, uint8_t *pMeas= urementDataReady); +long stmvl53lx_tv_dif(struct st_timeval *pstart_tv, struct st_timeval *pst= op_tv); +VL53LX_Error VL53LX_GetMultiRangingData(VL53LX_DEV Dev, VL53LX_MultiRangin= gData_t *pMultiRangingData); +VL53LX_Error VL53LX_get_histogram_debug_data(VL53LX_DEV Dev, VL53LX_histog= ram_bin_data_t *pdata); +VL53LX_Error VL53LX_get_additional_data(VL53LX_DEV Dev, VL53LX_additional_= data_t *pdata); +VL53LX_Error VL53LX_GetAdditionalData(VL53LX_DEV Dev, VL53LX_AdditionalDat= a_t *pAdditionalData); +VL53LX_Error VL53LX_clear_interrupt_and_enable_next_range(VL53LX_DEV Dev, = uint8_t measurement_mode); +VL53LX_Error VL53LX_ClearInterruptAndStartMeasurement(VL53LX_DEV Dev); +int stmvl53lx_intr_handler(struct stmvl53lx_data *data); +VL53LX_Error VL53LX_set_tuning_parm(VL53LX_DEV Dev, VL53LX_TuningParms tun= ing_parm_key, int32_t tuning_parm_value); +VL53LX_Error VL53LX_SetTuningParameter(VL53LX_DEV Dev, uint16_t TuningPara= meterId, int32_t TuningParameterValue); +VL53LX_Error VL53LX_GetTuningParameter(VL53LX_DEV Dev, uint16_t TuningPara= meterId, int32_t *pTuningParameterValue); +VL53LX_Error VL53LX_set_part_to_part_data(VL53LX_DEV Dev, VL53LX_calibrati= on_data_t *pcal_data); +VL53LX_Error VL53LX_get_current_xtalk_settings(VL53LX_DEV Dev, VL53LX_xtal= k_calibration_results_t *pxtalk); +VL53LX_Error VL53LX_set_current_xtalk_settings(VL53LX_DEV Dev, VL53LX_xtal= k_calibration_results_t *pxtalk); +VL53LX_Error VL53LX_SetCalibrationData(VL53LX_DEV Dev, VL53LX_CalibrationD= ata_t *pCalibrationData); +VL53LX_Error VL53LX_get_part_to_part_data(VL53LX_DEV Dev, VL53LX_calibrati= on_data_t *pcal_data); +void VL53LX_init_version(VL53LX_DEV Dev); +VL53LX_Error VL53LX_get_static_nvm_managed(VL53LX_DEV Dev, VL53LX_static_n= vm_managed_t *pdata); +VL53LX_Error VL53LX_i2c_decode_customer_nvm_managed(uint16_t buf_size, uin= t8_t *pbuffer, VL53LX_customer_nvm_managed_t *pdata); +VL53LX_Error VL53LX_get_customer_nvm_managed(VL53LX_DEV Dev, VL53LX_custom= er_nvm_managed_t *pdata); +VL53LX_Error VL53LX_i2c_decode_nvm_copy_data(uint16_t buf_size, uint8_t *p= buffer, VL53LX_nvm_copy_data_t *pdata); +VL53LX_Error VL53LX_get_nvm_copy_data(VL53LX_DEV Dev, VL53LX_nvm_copy_data= _t *pdata); +void VL53LX_copy_rtn_good_spads_to_buffer(VL53LX_nvm_copy_data_t *pdata, u= int8_t *pbuffer); +VL53LX_Error VL53LX_set_firmware_enable_register(VL53LX_DEV Dev, uint8_t v= alue); +VL53LX_Error VL53LX_disable_firmware(VL53LX_DEV Dev); +VL53LX_Error VL53LX_nvm_enable(VL53LX_DEV Dev, uint16_t nvm_ctrl_pulse_wid= th, int32_t nvm_power_up_delay_us); +VL53LX_Error VL53LX_nvm_read(VL53LX_DEV Dev, uint8_t start_address, uint8_= t count, uint8_t *pdata); +VL53LX_Error VL53LX_enable_firmware(VL53LX_DEV Dev); +VL53LX_Error VL53LX_nvm_disable(VL53LX_DEV Dev); +VL53LX_Error VL53LX_read_nvm_raw_data(VL53LX_DEV Dev, uint8_t start_addres= s, uint8_t count, uint8_t *pnvm_raw_data); +VL53LX_Error VL53LX_nvm_decode_optical_centre(uint16_t buf_size, uint8_t *= pbuffer, VL53LX_optical_centre_t *pdata); +VL53LX_Error VL53LX_read_nvm_optical_centre(VL53LX_DEV Dev, VL53LX_optical= _centre_t *pcentre); +VL53LX_Error VL53LX_nvm_decode_cal_peak_rate_map(uint16_t buf_size, uint8_= t *pbuffer, VL53LX_cal_peak_rate_map_t *pdata); +VL53LX_Error VL53LX_read_nvm_cal_peak_rate_map(VL53LX_DEV Dev, VL53LX_cal_= peak_rate_map_t *pcal_data); +VL53LX_Error VL53LX_nvm_decode_additional_offset_cal_data(uint16_t buf_siz= e, uint8_t *pbuffer, VL53LX_additional_offset_cal_data_t *pdata); +VL53LX_Error VL53LX_read_nvm_additional_offset_cal_data(VL53LX_DEV Dev, VL= 53LX_additional_offset_cal_data_t *pcal_data); +void VL53LX_spad_number_to_byte_bit_index(uint8_t spad_number, uint8_t *pb= yte_index, uint8_t *pbit_index, uint8_t *pbit_mask); +uint8_t VL53LX_is_aperture_location(uint8_t row, uint8_t col); +void VL53LX_decode_row_col(uint8_t spad_number, uint8_t *prow, uint8_t *pc= ol); +void VL53LX_decode_zone_size(uint8_t encoded_xy_size, uint8_t *pwidth, uin= t8_t *pheight); +void VL53LX_decode_zone_limits(uint8_t encoded_xy_centre, uint8_t encoded_= xy_size, int16_t *px_ll, int16_t *py_ll, int16_t *px_ur, int16_t *py_ur); +void VL53LX_calc_mm_effective_spads( + uint8_t encoded_mm_roi_centre, + uint8_t encoded_mm_roi_size, + uint8_t encoded_zone_centre, + uint8_t encoded_zone_size, + uint8_t *pgood_spads, + uint16_t aperture_attenuation, + uint16_t *pmm_inner_effective_spads, + uint16_t *pmm_outer_effective_spads); +VL53LX_Error VL53LX_nvm_decode_fmt_range_results_data(uint16_t buf_size, u= int8_t *pbuffer, VL53LX_decoded_nvm_fmt_range_data_t *pdata); +VL53LX_Error VL53LX_read_nvm_fmt_range_results_data(VL53LX_DEV Dev, uint16= _t range_results_select, VL53LX_decoded_nvm_fmt_range_data_t *prange_data); +VL53LX_Error VL53LX_get_mode_mitigation_roi(VL53LX_DEV Dev, VL53LX_user_zo= ne_t *pmm_roi); +VL53LX_Error VL53LX_read_p2p_data(VL53LX_DEV Dev); +VL53LX_Error VL53LX_init_refspadchar_config_struct(VL53LX_refspadchar_conf= ig_t *pdata); +VL53LX_Error VL53LX_init_ssc_config_struct(VL53LX_ssc_config_t *pdata); +VL53LX_Error VL53LX_init_xtalk_config_struct(VL53LX_customer_nvm_managed_t= *pnvm, VL53LX_xtalk_config_t *pdata); +VL53LX_Error VL53LX_init_xtalk_extract_config_struct(VL53LX_xtalkextract_c= onfig_t *pdata); +VL53LX_Error VL53LX_init_offset_cal_config_struct(VL53LX_offsetcal_config_= t *pdata); +VL53LX_Error VL53LX_init_zone_cal_config_struct(VL53LX_zonecal_config_t *p= data); +VL53LX_Error VL53LX_init_hist_post_process_config_struct(uint8_t xtalk_com= pensation_enable, VL53LX_hist_post_process_config_t *pdata); +VL53LX_Error VL53LX_init_hist_gen3_dmax_config_struct(VL53LX_hist_gen3_dma= x_config_t *pdata); +VL53LX_Error VL53LX_init_tuning_parm_storage_struct(VL53LX_tuning_parm_sto= rage_t *pdata); +void VL53LX_init_histogram_bin_data_struct(int32_t bin_value, uint16_t VL5= 3LX_p_021, VL53LX_histogram_bin_data_t *pdata); +void VL53LX_init_xtalk_bin_data_struct(uint32_t bin_value, uint16_t VL53LX= _p_021, VL53LX_xtalk_histogram_shape_t *pdata); +VL53LX_Error VL53LX_xtalk_cal_data_init(VL53LX_DEV Dev); +VL53LX_Error VL53LX_dynamic_xtalk_correction_output_init(VL53LX_LLDriverRe= sults_t *pres); +VL53LX_Error VL53LX_dynamic_xtalk_correction_data_init(VL53LX_DEV Dev); +VL53LX_Error VL53LX_low_power_auto_data_init(VL53LX_DEV Dev); +VL53LX_Error VL53LX_data_init(VL53LX_DEV Dev, uint8_t read_p2p_data); +VL53LX_Error VL53LX_set_dmax_mode(VL53LX_DEV Dev, VL53LX_DeviceDmaxMode dm= ax_mode); +VL53LX_Error VL53LX_DataInit(VL53LX_DEV Dev); +VL53LX_Error VL53LX_get_zone_config(VL53LX_DEV Dev, VL53LX_zone_config_t *= pzone_cfg); +VL53LX_Error VL53LX_GetUserROI(VL53LX_DEV Dev, VL53LX_UserRoi_t *pRoi); +VL53LX_Error VL53LX_GetDeviceInfo(VL53LX_DEV Dev, VL53LX_DeviceInfo_t *pVL= 53LX_DeviceInfo); +VL53LX_Error VL53LX_GetOpticalCenter(VL53LX_DEV Dev, FixPoint1616_t *pOpti= calCenterX, FixPoint1616_t *pOpticalCenterY); +void VL53LX_hist_get_bin_sequence_config(VL53LX_DEV Dev, VL53LX_histogram_= bin_data_t *pdata); +uint32_t VL53LX_duration_maths(uint32_t pll_period_us, uint32_t vcsel_parm= _pclks, uint32_t window_vclks, uint32_t elapsed_mclks); +void VL53LX_hist_calc_zero_distance_phase(VL53LX_histogram_bin_data_t *pda= ta); +void VL53LX_hist_estimate_ambient_from_ambient_bins(VL53LX_histogram_bin_d= ata_t *pdata); +VL53LX_Error VL53LX_get_histogram_bin_data(VL53LX_DEV Dev, VL53LX_histogra= m_bin_data_t *pdata); +VL53LX_Error VL53LX_hist_copy_and_scale_ambient_info(VL53LX_zone_hist_info= _t *pidata, VL53LX_histogram_bin_data_t *podata); +VL53LX_Error VL53LX_compute_histo_merge_nb(VL53LX_DEV Dev, uint8_t *histo_= merge_nb); +void VL53LX_hist_combine_mm1_mm2_offsets( + int16_t mm1_offset_mm, + int16_t mm2_offset_mm, + uint8_t encoded_mm_roi_centre, + uint8_t encoded_mm_roi_size, + uint8_t encoded_zone_centre, + uint8_t encoded_zone_size, + VL53LX_additional_offset_cal_data_t *pcal_data, + uint8_t *pgood_spads, + uint16_t aperture_attenuation, + int16_t *prange_offset_mm); +void VL53LX_calc_max_effective_spads(uint8_t encoded_zone_centre, uint8_t = encoded_zone_size, uint8_t *pgood_spads, uint16_t aperture_attenuation, uin= t16_t *pmax_effective_spads); +VL53LX_Error VL53LX_get_dmax_calibration_data(VL53LX_DEV Dev, VL53LX_Devic= eDmaxMode dmax_mode, VL53LX_dmax_calibration_data_t *pdmax_cal); +VL53LX_Error VL53LX_f_031(VL53LX_histogram_bin_data_t *pidata, VL53LX_hist= ogram_bin_data_t *podata); +VL53LX_Error VL53LX_f_032(uint32_t mean_offset, int16_t xgradient, int16_t= ygradient, int8_t centre_offset_x, int8_t centre_offset_y, uint16_t roi_ef= fective_spads, uint8_t roi_centre_spad, uint8_t roi_xy_size, uint32_t *xtal= k_rate_kcps); +VL53LX_Error VL53LX_f_033(VL53LX_histogram_bin_data_t *phist_data, VL53LX_= xtalk_histogram_shape_t *pxtalk_data, uint32_t xtalk_rate_kcps, VL53LX_hist= ogram_bin_data_t *pxtalkcount_data); +void VL53LX_copy_xtalk_bin_data_to_histogram_data_struct(VL53LX_xtalk_hist= ogram_shape_t *pxtalk, VL53LX_histogram_bin_data_t *phist); +void VL53LX_f_003(VL53LX_hist_gen3_algo_private_data_t *palgo); +void VL53LX_hist_find_min_max_bin_values(VL53LX_histogram_bin_data_t *pdat= a); +uint32_t VL53LX_isqrt(uint32_t num); +void VL53LX_hist_estimate_ambient_from_thresholded_bins(int32_t ambient_th= reshold_sigma, VL53LX_histogram_bin_data_t *pdata); +void VL53LX_hist_remove_ambient_bins(VL53LX_histogram_bin_data_t *pdata); +int8_t VL53LX_f_030(VL53LX_histogram_bin_data_t *pdata1, VL53LX_histogram_= bin_data_t *pdata2); +void VL53LX_f_005(VL53LX_histogram_bin_data_t *pxtalk, VL53LX_histogram_bi= n_data_t *pbins, VL53LX_histogram_bin_data_t *pxtalk_realigned); +uint16_t VL53LX_rate_maths(int32_t VL53LX_p_018, uint32_t time_us); +uint32_t VL53LX_events_per_spad_maths(int32_t VL53LX_p_010, uint16_t num_s= pads, uint32_t duration); +uint32_t VL53LX_f_002(uint32_t events_threshold, uint32_t ref_signal_event= s, uint32_t ref_distance_mm, uint32_t signal_thresh_sigma); +VL53LX_Error VL53LX_f_001( + uint16_t target_reflectance, + VL53LX_dmax_calibration_data_t *pcal, + VL53LX_hist_gen3_dmax_config_t *pcfg, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_gen3_dmax_private_data_t *pdata, + int16_t *pambient_dmax_mm); +VL53LX_Error VL53LX_f_006( + uint16_t ambient_threshold_events_scaler, + int32_t ambient_threshold_sigma, + int32_t min_ambient_threshold_events, + uint8_t algo__crosstalk_compensation_enable, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_histogram_bin_data_t *pxtalk, + VL53LX_hist_gen3_algo_private_data_t *palgo); +VL53LX_Error VL53LX_f_007(VL53LX_hist_gen3_algo_private_data_t *palgo); +VL53LX_Error VL53LX_f_008(VL53LX_hist_gen3_algo_private_data_t *palgo); +VL53LX_Error VL53LX_f_009(VL53LX_hist_gen3_algo_private_data_t *palgo); +VL53LX_Error VL53LX_f_010(uint8_t pulse_no, VL53LX_histogram_bin_data_t *p= bins, VL53LX_hist_gen3_algo_private_data_t *palgo); +VL53LX_Error VL53LX_f_011( + uint8_t pulse_no, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_gen3_algo_private_data_t *palgo, + int32_t pad_value, + VL53LX_histogram_bin_data_t *ppulse); +VL53LX_Error VL53LX_f_014( + uint8_t bin, + uint8_t sigma_estimator__sigma_ref_mm, + uint8_t VL53LX_p_030, + uint8_t VL53LX_p_051, + uint8_t crosstalk_compensation_enable, + VL53LX_histogram_bin_data_t *phist_data_ap, + VL53LX_histogram_bin_data_t *phist_data_zp, + VL53LX_histogram_bin_data_t *pxtalk_hist, + uint16_t *psigma_est); +VL53LX_Error VL53LX_f_015(uint8_t pulse_no, uint8_t clip_events, VL53LX_hi= stogram_bin_data_t *pbins, VL53LX_hist_gen3_algo_private_data_t *palgo); +VL53LX_Error VL53LX_f_016(VL53LX_HistTargetOrder target_order, VL53LX_hist= _gen3_algo_private_data_t *palgo); +void VL53LX_f_017( + uint8_t range_id, + uint8_t valid_phase_low, + uint8_t valid_phase_high, + uint16_t sigma_thres, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_pulse_data_t *ppulse, + VL53LX_range_data_t *pdata); +VL53LX_Error VL53LX_f_018( + uint16_t vcsel_width, + uint16_t fast_osc_frequency, + uint32_t total_periods_elapsed, + uint16_t VL53LX_p_004, + VL53LX_range_data_t *pdata, + uint8_t histo_merge_nb); +void VL53LX_f_019(uint16_t gain_factor, int16_t range_offset_mm, VL53LX_ra= nge_data_t *pdata); +VL53LX_Error VL53LX_f_020(int16_t VL53LX_p_019, int16_t VL53LX_p_024, uint= 8_t VL53LX_p_030, uint8_t clip_events, VL53LX_histogram_bin_data_t *pbins, = uint32_t *pphase); +void VL53LX_f_022(uint8_t VL53LX_p_032, uint8_t filter_woi, VL53LX_histogr= am_bin_data_t *pbins, int32_t *pa, int32_t *pb, int32_t *pc); +VL53LX_Error VL53LX_f_023( + uint8_t sigma_estimator__sigma_ref_mm, + uint32_t VL53LX_p_007, + uint32_t VL53LX_p_032, + uint32_t VL53LX_p_001, + uint32_t a_zp, + uint32_t c_zp, + uint32_t bx, + uint32_t ax_zp, + uint32_t cx_zp, + uint32_t VL53LX_p_028, + uint16_t fast_osc_frequency, + uint16_t *psigma_est); +VL53LX_Error VL53LX_f_025( + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_hist_post_process_config_t *ppost_cfg, + VL53LX_histogram_bin_data_t *pbins_input, + VL53LX_histogram_bin_data_t *pxtalk, + VL53LX_hist_gen3_algo_private_data_t *palgo3, + VL53LX_hist_gen4_algo_filtered_data_t *pfiltered, + VL53LX_hist_gen3_dmax_private_data_t *pdmax_algo, + VL53LX_range_results_t *presults, + uint8_t histo_merge_nb); +VL53LX_Error VL53LX_f_026( + uint8_t pulse_no, + VL53LX_histogram_bin_data_t *ppulse, + VL53LX_hist_gen3_algo_private_data_t *palgo3, + VL53LX_hist_gen4_algo_filtered_data_t *pfiltered); +VL53LX_Error VL53LX_f_027(uint8_t pulse_no, uint16_t noise_threshold, VL53= LX_hist_gen4_algo_filtered_data_t *pfiltered, VL53LX_hist_gen3_algo_private= _data_t *palgo3); +VL53LX_Error VL53LX_f_028( + uint8_t bin, + int32_t VL53LX_p_007, + int32_t VL53LX_p_032, + int32_t VL53LX_p_001, + int32_t ax, + int32_t bx, + int32_t cx, + int32_t VL53LX_p_028, + uint8_t VL53LX_p_030, + uint32_t *pmean_phase); +uint32_t VL53LX_calc_pll_period_mm(uint16_t fast_osc_frequency); +int32_t VL53LX_range_maths( + uint16_t fast_osc_frequency, + uint16_t VL53LX_p_014, + uint16_t zero_distance_phase, + uint8_t fractional_bits, + int32_t gain_factor, + int32_t range_offset_mm); +uint16_t VL53LX_rate_per_spad_maths(uint32_t frac_bits, uint32_t peak_coun= t_rate, uint16_t num_spads, uint32_t max_output_value); +VL53LX_Error VL53LX_hist_process_data( + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_hist_post_process_config_t *ppost_cfg, + VL53LX_histogram_bin_data_t *pbins_input, + VL53LX_xtalk_histogram_data_t *pxtalk_shape, + uint8_t *pArea1, + uint8_t *pArea2, + VL53LX_range_results_t *presults, + uint8_t *HistMergeNumber); +VL53LX_Error VL53LX_hist_wrap_dmax(VL53LX_hist_post_process_config_t *phis= tpostprocess, VL53LX_histogram_bin_data_t *pcurrent, int16_t *pwrap_dmax_mm= ); +VL53LX_Error VL53LX_ipp_hist_process_data( + VL53LX_DEV Dev, + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_hist_post_process_config_t *ppost_cfg, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_xtalk_histogram_data_t *pxtalk, + uint8_t *pArea1, + uint8_t *pArea2, + uint8_t *phisto_merge_nb, + VL53LX_range_results_t *presults); +VL53LX_Error VL53LX_hist_events_consistency_check( + uint8_t event_sigma, + uint16_t min_effective_spad_count, + VL53LX_zone_hist_info_t *phist_prev, + VL53LX_object_data_t *prange_prev, + VL53LX_range_data_t *prange_curr, + int32_t *pevents_tolerance, + int32_t *pevents_delta, + VL53LX_DeviceError *prange_status); +VL53LX_Error VL53LX_hist_phase_consistency_check(VL53LX_DEV Dev, VL53LX_zo= ne_hist_info_t *phist_prev, VL53LX_zone_objects_t *prange_prev, VL53LX_rang= e_results_t *prange_curr); +VL53LX_Error VL53LX_hist_merged_pulse_check(int16_t min_max_tolerance_mm, = VL53LX_range_data_t *pdata, VL53LX_DeviceError *prange_status); +VL53LX_Error VL53LX_hist_xmonitor_consistency_check(VL53LX_DEV Dev, VL53LX= _zone_hist_info_t *phist_prev, VL53LX_zone_objects_t *prange_prev, VL53LX_r= ange_data_t *prange_curr); +void VL53LX_init_system_results(VL53LX_system_results_t *pdata); +void VL53LX_hist_copy_results_to_sys_and_core( + VL53LX_histogram_bin_data_t *pbins, + VL53LX_range_results_t *phist, + VL53LX_system_results_t *psys, + VL53LX_core_results_t *pcore); +VL53LX_Error VL53LX_dynamic_zone_update(VL53LX_DEV Dev, VL53LX_range_resul= ts_t *presults); +void VL53LX_copy_hist_bins_to_static_cfg(VL53LX_histogram_config_t *phisto= gram, VL53LX_static_config_t *pstatic, VL53LX_timing_config_t *ptiming); +VL53LX_Error VL53LX_multizone_hist_bins_update(VL53LX_DEV Dev); +VL53LX_Error VL53LX_dynamic_xtalk_correction_calc_required_samples(VL53LX_= DEV Dev); +VL53LX_Error VL53LX_dynamic_xtalk_correction_calc_new_xtalk( + VL53LX_DEV Dev, + uint32_t xtalk_offset_out, + VL53LX_smudge_corrector_config_t *pconfig, + VL53LX_smudge_corrector_data_t *pout, + uint8_t add_smudge, + uint8_t soft_update + ); +VL53LX_Error VL53LX_dynamic_xtalk_correction_corrector(VL53LX_DEV Dev); +VL53LX_Error VL53LX_i2c_decode_debug_results(uint16_t buf_size, uint8_t *p= buffer, VL53LX_debug_results_t *pdata); +VL53LX_Error VL53LX_i2c_decode_core_results(uint16_t buf_size, uint8_t *pb= uffer, VL53LX_core_results_t *pdata); +VL53LX_Error VL53LX_i2c_decode_system_results(uint16_t buf_size, uint8_t *= pbuffer, VL53LX_system_results_t *pdata); +VL53LX_Error VL53LX_get_measurement_results(VL53LX_DEV Dev, VL53LX_DeviceR= esultsLevel device_results_level); +void VL53LX_copy_sys_and_core_results_to_range_results(int32_t gain_factor= , VL53LX_system_results_t *psys, VL53LX_core_results_t *pcore, VL53LX_range= _results_t *presults); +VL53LX_Error VL53LX_low_power_auto_setup_manual_calibration(VL53LX_DEV Dev= ); +VL53LX_Error VL53LX_low_power_auto_update_DSS(VL53LX_DEV Dev); +VL53LX_Error VL53LX_check_ll_driver_rd_state(VL53LX_DEV Dev); +VL53LX_Error VL53LX_set_ref_spad_char_config( + VL53LX_DEV Dev, + uint8_t vcsel_period_a, + uint32_t phasecal_timeout_us, + uint16_t total_rate_target_mcps, + uint16_t max_count_rate_rtn_limit_mcps, + uint16_t min_count_rate_rtn_limit_mcps, + uint16_t fast_osc_frequency); +VL53LX_Error VL53LX_start_test(VL53LX_DEV Dev, uint8_t test_mode__ctrl); +VL53LX_Error VL53LX_wait_for_test_completion(VL53LX_DEV Dev); +VL53LX_Error VL53LX_clear_interrupt(VL53LX_DEV Dev); +VL53LX_Error VL53LX_run_device_test(VL53LX_DEV Dev, VL53LX_DeviceTestMode = device_test_mode); +VL53LX_Error VL53LX_run_ref_spad_char(VL53LX_DEV Dev, VL53LX_Error *pcal_s= tatus); +VL53LX_Error VL53LX_PerformRefSpadManagement(VL53LX_DEV Dev); +void VL53LX_hist_xtalk_extract_data_init(VL53LX_hist_xtalk_extract_data_t = *pxtalk_data); +VL53LX_Error VL53LX_wait_for_range_completion(VL53LX_DEV Dev); +VL53LX_Error VL53LX_hist_xtalk_extract_calc_window( + int16_t target_distance_mm, + uint16_t target_width_oversize, + VL53LX_histogram_bin_data_t *phist_bins, + VL53LX_hist_xtalk_extract_data_t *pxtalk_data); +VL53LX_Error VL53LX_hist_xtalk_extract_calc_event_sums(VL53LX_histogram_bi= n_data_t *phist_bins, VL53LX_hist_xtalk_extract_data_t *pxtalk_data); +VL53LX_Error VL53LX_hist_xtalk_extract_update( + int16_t target_distance_mm, + uint16_t target_width_oversize, + VL53LX_histogram_bin_data_t *phist_bins, + VL53LX_hist_xtalk_extract_data_t *pxtalk_data); +VL53LX_Error VL53LX_hist_xtalk_extract_calc_rate_per_spad(VL53LX_hist_xtal= k_extract_data_t *pxtalk_data); +VL53LX_Error VL53LX_hist_xtalk_extract_calc_shape(VL53LX_hist_xtalk_extrac= t_data_t *pxtalk_data, VL53LX_xtalk_histogram_shape_t *pxtalk_shape); +VL53LX_Error VL53LX_hist_xtalk_extract_fini( + VL53LX_histogram_bin_data_t *phist_bins, + VL53LX_hist_xtalk_extract_data_t *pxtalk_data, + VL53LX_xtalk_calibration_results_t *pxtalk_cal, + VL53LX_xtalk_histogram_shape_t *pxtalk_shape); +VL53LX_Error VL53LX_run_hist_xtalk_extraction(VL53LX_DEV Dev, int16_t cal_= distance_mm, VL53LX_Error *pcal_status); +VL53LX_Error VL53LX_PerformXTalkCalibration(VL53LX_DEV Dev); +VL53LX_Error VL53LX_PerformOffsetSimpleCalibration(VL53LX_DEV Dev, int32_t= CalDistanceMilliMeter); +VL53LX_Error VL53LX_GetDistanceMode(VL53LX_DEV Dev, VL53LX_DistanceModes *= pDistanceMode); +VL53LX_Error VL53LX_PerformOffsetPerVcselCalibration(VL53LX_DEV Dev, int32= _t CalDistanceMilliMeter); +VL53LX_Error VL53LX_PerformOffsetZeroDistanceCalibration(VL53LX_DEV Dev); +int stmvl53lx_setup(struct stmvl53lx_data *data); +void stmvl53lx_cleanup(struct stmvl53lx_data *data); +void stmvl53lx_pm_suspend_stop(struct stmvl53lx_data *data); +int stmvl53lx_init_i2c(void); +void stmvl53lx_exit_i2c(void *i2c_object); +int stmvl53lx_power_up_i2c(void *object); +int stmvl53lx_power_down_i2c(void *i2c_object); +int stmvl53lx_reset_release_i2c(void *i2c_object); +int stmvl53lx_reset_hold_i2c(void *i2c_object); +void stmvl53lx_clean_up_i2c(void); +int stmvl53lx_start_intr(void *object, int *poll_mode); +void *stmvl53lx_get(void *object); + +void st_gettimeofday(struct st_timeval *tv) +{ + struct timespec64 now; + + ktime_get_real_ts64(&now); + tv->tv_sec =3D now.tv_sec; + tv->tv_usec =3D now.tv_nsec/1000; +} + +#if STMVL53LX_LOG_CCI_TIMING +static uint32_t tv_elapsed_us(struct st_timeval *tv) +{ + struct st_timeval now; + + st_gettimeofday(&now); + return (now.tv_sec - tv->tv_sec) * 1000000 + (now.tv_usec - tv->tv_usec); +} + +#define cci_access_var struct st_timeval cci_log_start_tv +#define cci_access_start() st_gettimeofday(&cci_log_start_tv) +#define cci_access_over(fmt, ...) printk("cci_timing %d us" fmt "\n", tv_e= lapsed_us(&cci_log_start_tv), ##__VA_ARGS__) +#else +#define cci_access_var +#define cci_access_start(...) ((void)0) +#define cci_access_over(...) ((void)0) +#endif + +static int get_xsdn(struct device *dev, struct i2c_data *i2c_data) +{ + int rc =3D 0; + + i2c_data->io_flag.xsdn_owned =3D 0; + if (i2c_data->xsdn_gpio =3D=3D -1) { + vl53lx_errmsg("reset gpio is required"); + rc =3D -ENODEV; + goto no_gpio; + } + + vl53lx_dbgmsg("request xsdn_gpio %d", i2c_data->xsdn_gpio); + rc =3D gpio_request(i2c_data->xsdn_gpio, "vl53lx_xsdn"); + if (rc) { + vl53lx_errmsg("fail to acquire xsdn %d", rc); + goto request_failed; + } + + rc =3D gpio_direction_output(i2c_data->xsdn_gpio, 0); + if (rc) { + vl53lx_errmsg("fail to configure xsdn as output %d", rc); + goto direction_failed; + } + i2c_data->io_flag.xsdn_owned =3D 1; + + return rc; + +direction_failed: + gpio_free(i2c_data->xsdn_gpio); + +request_failed: +no_gpio: + return rc; +} + +static void put_xsdn(struct i2c_data *i2c_data) +{ + if (i2c_data->io_flag.xsdn_owned) { + vl53lx_dbgmsg("release xsdn_gpio %d", i2c_data->xsdn_gpio); + gpio_free(i2c_data->xsdn_gpio); + i2c_data->io_flag.xsdn_owned =3D 0; + } + i2c_data->xsdn_gpio =3D -1; +} + +static int get_pwren(struct device *dev, struct i2c_data *i2c_data) +{ + int rc =3D 0; + + i2c_data->io_flag.pwr_owned =3D 0; + if (i2c_data->pwren_gpio =3D=3D -1) { + vl53lx_wanrmsg("pwren gpio disable"); + goto no_gpio; + } + + vl53lx_dbgmsg("request pwren_gpio %d", i2c_data->pwren_gpio); + rc =3D gpio_request(i2c_data->pwren_gpio, "vl53lx_pwren"); + if (rc) { + vl53lx_errmsg("fail to acquire pwren %d", rc); + goto request_failed; + } + + rc =3D gpio_direction_output(i2c_data->pwren_gpio, 0); + if (rc) { + vl53lx_errmsg("fail to configure pwren as output %d", rc); + goto direction_failed; + } + i2c_data->io_flag.pwr_owned =3D 1; + + return rc; + +direction_failed: + gpio_free(i2c_data->xsdn_gpio); + +request_failed: +no_gpio: + return rc; +} + +static void put_pwren(struct i2c_data *i2c_data) +{ + if (i2c_data->io_flag.pwr_owned) { + vl53lx_dbgmsg("release xsdn_gpio %d", i2c_data->xsdn_gpio); + gpio_free(i2c_data->pwren_gpio); + i2c_data->io_flag.pwr_owned =3D 0; + } + i2c_data->pwren_gpio =3D -1; +} + +static int get_intr(struct device *dev, struct i2c_data *i2c_data) +{ + int rc =3D 0; + + i2c_data->io_flag.intr_owned =3D 0; + if (i2c_data->intr_gpio =3D=3D -1) { + vl53lx_wanrmsg("no interrupt gpio"); + goto no_gpio; + } + + vl53lx_dbgmsg("request intr_gpio %d", i2c_data->intr_gpio); + rc =3D gpio_request(i2c_data->intr_gpio, "vl53lx_intr"); + if (rc) { + vl53lx_errmsg("fail to acquire intr %d", rc); + goto request_failed; + } + + rc =3D gpio_direction_input(i2c_data->intr_gpio); + if (rc) { + vl53lx_errmsg("fail to configure intr as input %d", rc); + goto direction_failed; + } + + i2c_data->irq =3D gpio_to_irq(i2c_data->intr_gpio); + if (i2c_data->irq < 0) { + vl53lx_errmsg("fail to map GPIO: %d to interrupt:%d\n", i2c_data->intr_g= pio, i2c_data->irq); + goto irq_failed; + } + i2c_data->io_flag.intr_owned =3D 1; + + return rc; + +irq_failed: +direction_failed: + gpio_free(i2c_data->intr_gpio); + +request_failed: +no_gpio: + return rc; +} + +static void put_intr(struct i2c_data *i2c_data) +{ + if (i2c_data->io_flag.intr_owned) { + if (i2c_data->io_flag.intr_started) { + free_irq(i2c_data->irq, i2c_data); + i2c_data->io_flag.intr_started =3D 0; + } + vl53lx_dbgmsg("release intr_gpio %d", i2c_data->intr_gpio); + gpio_free(i2c_data->intr_gpio); + i2c_data->io_flag.intr_owned =3D 0; + } + i2c_data->intr_gpio =3D -1; +} + +static int handle_i2c_address_device_change_lock(struct i2c_data *data) +{ + struct i2c_client *client =3D (struct i2c_client *) data->client; + uint8_t buffer[3]; + struct i2c_msg msg; + int rc =3D 0; + + vl53lx_dbgmsg("change device i2c address from 0x%02x to 0x%02x", data->bo= ot_reg, client->addr); + + usleep_range(VL53LX_FIRMWARE_BOOT_TIME_US, VL53LX_FIRMWARE_BOOT_TIME_US += 1); + + buffer[0] =3D (VL53LX_I2C_SLAVE__DEVICE_ADDRESS >> 8) & 0xFF; + buffer[1] =3D (VL53LX_I2C_SLAVE__DEVICE_ADDRESS >> 0) & 0xFF; + buffer[2] =3D client->addr; + msg.addr =3D data->boot_reg; + msg.flags =3D client->flags; + msg.buf =3D buffer; + msg.len =3D 3; + if (i2c_transfer(client->adapter, &msg, 1) !=3D 1) { + rc =3D -ENXIO; + vl53lx_errmsg("Fail to change i2c address to 0x%02x", client->addr); + } + + return rc; +} + +static int release_reset(struct i2c_data *data) +{ + struct i2c_client *client =3D (struct i2c_client *) data->client; + int rc =3D 0; + bool is_address_change =3D client->addr !=3D data->boot_reg; + + if (is_address_change) + mutex_lock(&dev_addr_change_mutex); + + gpio_set_value(data->xsdn_gpio, 1); + if (is_address_change) { + rc =3D handle_i2c_address_device_change_lock(data); + if (rc) + gpio_set_value(data->xsdn_gpio, 0); + } + + if (is_address_change) + mutex_unlock(&dev_addr_change_mutex); + + return rc; +} + +VL53LX_Error VL53LX_WaitUs(VL53LX_DEV pdev, int32_t wait_us) +{ + struct stmvl53lx_data *data; + + data =3D (struct stmvl53lx_data *)container_of(pdev, struct stmvl53lx_dat= a, stdev); + + if (!data->is_delay_allowed) + return VL53LX_ERROR_PLATFORM_SPECIFIC_START; + + if (wait_us < 10) + udelay(wait_us); + else if (wait_us < 20000) + usleep_range(wait_us, wait_us + 1); + else + msleep(wait_us / 1000); + + return VL53LX_ERROR_NONE; +} + +VL53LX_Error VL53LX_WaitMs(VL53LX_DEV pdev, int32_t wait_ms) +{ + return VL53LX_WaitUs(pdev, wait_ms * 1000); +} + +static int cci_write(struct stmvl53lx_data *dev, int index, uint8_t *data,= uint16_t len) +{ + uint8_t buffer[STMVL53LX_MAX_CCI_XFER_SZ + 2]; + struct i2c_msg msg; + struct i2c_data *i2c_client_obj =3D (struct i2c_data *)dev->client_object; + struct i2c_client *client =3D (struct i2c_client *)i2c_client_obj->client; + int rc; + + cci_access_var; + if (len > STMVL53LX_MAX_CCI_XFER_SZ || len =3D=3D 0) { + vl53lx_errmsg("invalid len %d\n", len); + return -1; + } + cci_access_start(); + buffer[0] =3D (index >> 8) & 0xFF; + buffer[1] =3D (index >> 0) & 0xFF; + memcpy(buffer + 2, data, len); + msg.addr =3D client->addr; + msg.flags =3D client->flags; + msg.buf =3D buffer; + msg.len =3D len + 2; + + rc =3D i2c_transfer(client->adapter, &msg, 1); + if (rc !=3D 1) { + vl53lx_errmsg("wr i2c_transfer err:%d, index 0x%x len %d\n", rc, index, = len); + } + cci_access_over("rd status %d long %d ", rc !=3D 1, len); + return rc !=3D 1; +} + +static int cci_read(struct stmvl53lx_data *dev, int index, uint8_t *data, = uint16_t len) +{ + uint8_t buffer[2]; + struct i2c_msg msg[2]; + struct i2c_data *i2c_client_obj =3D (struct i2c_data *)dev->client_object; + struct i2c_client *client =3D (struct i2c_client *)i2c_client_obj->client; + int rc; + + cci_access_var; + if (len > STMVL53LX_MAX_CCI_XFER_SZ || len =3D=3D 0) { + vl53lx_errmsg("invalid len %d\n", len); + return -1; + } + cci_access_start(); + + buffer[0] =3D (index >> 8) & 0xFF; + buffer[1] =3D (index >> 0) & 0xFF; + + msg[0].addr =3D client->addr; + msg[0].flags =3D client->flags; + msg[0].buf =3D buffer; + msg[0].len =3D 2; + + msg[1].addr =3D client->addr; + msg[1].flags =3D I2C_M_RD | client->flags; + msg[1].buf =3D data; + msg[1].len =3D len; + + rc =3D i2c_transfer(client->adapter, msg, 2); + if (rc !=3D 2) { + pr_err("%s: i2c_transfer :%d, @%x index 0x%x len %d\n", __func__, rc, cl= ient->addr, index, len); + } + cci_access_over(" wr len %d status %d", rc !=3D 2, len); + return rc !=3D 2; +} + +static uint32_t tv_elapsed_ms(struct st_timeval *tv) +{ + struct st_timeval now; + + st_gettimeofday(&now); + return (now.tv_sec - tv->tv_sec) * 1000 + (now.tv_usec - tv->tv_usec) / 1= 000; +} + +static int is_time_over(struct st_timeval *tv, uint32_t msec) +{ + return tv_elapsed_ms(tv) >=3D msec; +} + +VL53LX_Error VL53LX_WaitValueMaskEx(VL53LX_DEV pdev, uint32_t timeout_ms, = uint16_t index, uint8_t value, uint8_t mask, uint32_t poll_delay_ms) +{ + struct st_timeval start_tv; + struct stmvl53lx_data *dev; + int rc, time_over; + uint8_t rd_val; + + dev =3D (struct stmvl53lx_data *)container_of(pdev, struct stmvl53lx_data= , stdev); + + st_gettimeofday(&start_tv); + do { + rc =3D cci_read(dev, index, &rd_val, 1); + if (rc) + return VL53LX_ERROR_CONTROL_INTERFACE; + if ((rd_val & mask) =3D=3D value) { + poll_timing_log(&start_tv); + return VL53LX_ERROR_NONE; + } + vl53lx_dbgmsg("poll @%x %x & %d !=3D %x", index, rd_val, mask, value); + time_over =3D is_time_over(&start_tv, timeout_ms); + if (!time_over) + msleep(poll_delay_ms); + } while (!time_over); + vl53lx_errmsg("time over %d ms", timeout_ms); + return VL53LX_ERROR_TIME_OUT; +} + +void VL53LX_init_ll_driver_state(VL53LX_DEV Dev, VL53LX_DeviceState device= _state) +{ + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_ll_driver_state_t *pstate =3D &(pdev->ll_state); + + pstate->cfg_device_state =3D device_state; + pstate->cfg_stream_count =3D 0; + pstate->cfg_gph_id =3D VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->cfg_timing_status =3D 0; + pstate->cfg_zone_id =3D 0; + + pstate->rd_device_state =3D device_state; + pstate->rd_stream_count =3D 0; + pstate->rd_gph_id =3D VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->rd_timing_status =3D 0; + pstate->rd_zone_id =3D 0; +} + +VL53LX_Error VL53LX_poll_for_boot_completion(VL53LX_DEV Dev, uint32_t time= out_ms) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + status =3D VL53LX_WaitUs(Dev, VL53LX_FIRMWARE_BOOT_TIME_US); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WaitValueMaskEx(Dev, timeout_ms, VL53LX_FIRMWARE__SYST= EM_STATUS, 0x01, 0x01, VL53LX_POLLING_DELAY_MS); + + if (status =3D=3D VL53LX_ERROR_NONE) + VL53LX_init_ll_driver_state(Dev, VL53LX_DEVICESTATE_SW_STANDBY); + + return status; +} + +VL53LX_Error VL53LX_WaitDeviceBooted(VL53LX_DEV Dev) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + Status =3D VL53LX_poll_for_boot_completion(Dev, VL53LX_BOOT_COMPLETION_PO= LLING_TIMEOUT_MS); + + return Status; +} + +static int stmvl53lx_input_setup(struct stmvl53lx_data *data) +{ + int rc =3D 0; + struct input_dev *idev; + idev =3D input_allocate_device(); + if (idev =3D=3D NULL) { + rc =3D -ENOMEM; + vl53lx_errmsg("%d error:%d\n", __LINE__, rc); + goto exit_err; + } + + set_bit(EV_ABS, idev->evbit); + + input_set_abs_params(idev, ABS_DISTANCE, 0, 0xff, 0, 0); + input_set_abs_params(idev, ABS_HAT0X, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_HAT0Y, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_HAT1X, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_HAT1Y, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_HAT2X, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_HAT2Y, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_HAT3X, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_HAT3Y, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_WHEEL, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_TILT_Y, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_BRAKE, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_TILT_X, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_TOOL_WIDTH, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_THROTTLE, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_RUDDER, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_MISC, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_VOLUME, 0, 0xffffffff, 0, 0); + input_set_abs_params(idev, ABS_GAS, 0, 0xffffffff, 0, 0); + + idev->name =3D "STM VL53LX proximity sensor"; + rc =3D input_register_device(idev); + if (rc) { + rc =3D -ENOMEM; + vl53lx_errmsg("%d error:%d\n", __LINE__, rc); + goto exit_free_dev_ps; + } + input_set_drvdata(idev, data); + data->input_dev_ps =3D idev; + return 0; + +exit_free_dev_ps: + input_free_device(data->input_dev_ps); +exit_err: + return rc; +} + +uint32_t VL53LX_calc_pll_period_us(uint16_t fast_osc_frequency) +{ + uint32_t pll_period_us =3D 0; + + if (fast_osc_frequency > 0) + pll_period_us =3D (0x01 << 30) / fast_osc_frequency; + return pll_period_us; +} + +uint8_t VL53LX_decode_vcsel_period(uint8_t vcsel_period_reg) +{ + uint8_t VL53LX_p_030 =3D 0; + + VL53LX_p_030 =3D (vcsel_period_reg + 1) << 1; + return VL53LX_p_030; +} + + +uint32_t VL53LX_calc_macro_period_us(uint16_t fast_osc_frequency, uint8_t = VL53LX_p_005) +{ + uint32_t pll_period_us =3D 0; + uint8_t VL53LX_p_030 =3D 0; + uint32_t macro_period_us =3D 0; + + pll_period_us =3D VL53LX_calc_pll_period_us(fast_osc_frequency); + + VL53LX_p_030 =3D VL53LX_decode_vcsel_period(VL53LX_p_005); + + macro_period_us =3D (uint32_t)VL53LX_MACRO_PERIOD_VCSEL_PERIODS * pll_per= iod_us; + macro_period_us =3D macro_period_us >> 6; + + macro_period_us =3D macro_period_us * (uint32_t)VL53LX_p_030; + macro_period_us =3D macro_period_us >> 6; + + return macro_period_us; +} + +uint32_t VL53LX_calc_timeout_us(uint32_t timeout_mclks, uint32_t macro_per= iod_us) +{ + uint32_t timeout_us =3D 0; + uint64_t tmp =3D 0; + + + tmp =3D (uint64_t)timeout_mclks * (uint64_t)macro_period_us; + tmp +=3D 0x00800; + tmp =3D tmp >> 12; + + timeout_us =3D (uint32_t)tmp; + + return timeout_us; +} + +uint32_t VL53LX_decode_timeout(uint16_t encoded_timeout) +{ + uint32_t timeout_macro_clks =3D 0; + + timeout_macro_clks =3D ((uint32_t) (encoded_timeout & 0x00FF) << (uint32_= t) ((encoded_timeout & 0xFF00) >> 8)) + 1; + + return timeout_macro_clks; +} + +uint32_t VL53LX_calc_decoded_timeout_us( + uint16_t timeout_encoded, + uint32_t macro_period_us) +{ + uint32_t timeout_mclks =3D 0; + uint32_t timeout_us =3D 0; + + timeout_mclks =3D VL53LX_decode_timeout(timeout_encoded); + + timeout_us =3D VL53LX_calc_timeout_us(timeout_mclks, macro_period_us); + + return timeout_us; +} + +VL53LX_Error VL53LX_get_timeouts_us(VL53LX_DEV Dev, uint32_t *pphasecal_co= nfig_timeout_us, uint32_t *pmm_config_timeout_us, uint32_t *prange_config_t= imeout_us) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + uint32_t macro_period_us =3D 0; + uint16_t timeout_encoded =3D 0; + + if (pdev->stat_nvm.osc_measured__fast_osc__frequency =3D=3D 0) + status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + + if (status =3D=3D VL53LX_ERROR_NONE) { + macro_period_us =3D VL53LX_calc_macro_period_us(pdev->stat_nvm.osc_measu= red__fast_osc__frequency, pdev->tim_cfg.range_config__vcsel_period_a); + + *pphasecal_config_timeout_us =3D VL53LX_calc_timeout_us((uint32_t)pdev->= gen_cfg.phasecal_config__timeout_macrop, macro_period_us); + + timeout_encoded =3D (uint16_t)pdev->tim_cfg.mm_config__timeout_macrop_a_= hi; + timeout_encoded =3D (timeout_encoded << 8) + (uint16_t)pdev->tim_cfg.mm_= config__timeout_macrop_a_lo; + + *pmm_config_timeout_us =3D VL53LX_calc_decoded_timeout_us(timeout_encode= d, macro_period_us); + + timeout_encoded =3D (uint16_t)pdev->tim_cfg.range_config__timeout_macrop= _a_hi; + timeout_encoded =3D (timeout_encoded << 8) + (uint16_t)pdev->tim_cfg.ran= ge_config__timeout_macrop_a_lo; + + *prange_config_timeout_us =3D VL53LX_calc_decoded_timeout_us(timeout_enc= oded, macro_period_us); + + pdev->phasecal_config_timeout_us =3D *pphasecal_config_timeout_us; + pdev->mm_config_timeout_us =3D *pmm_config_timeout_us; + pdev->range_config_timeout_us =3D *prange_config_timeout_us; + + } + + return status; +} + +uint32_t VL53LX_calc_timeout_mclks(uint32_t timeout_us, uint32_t macro_per= iod_us) +{ + uint32_t timeout_mclks =3D 0; + + if (macro_period_us =3D=3D 0) + timeout_mclks =3D 0; + else + timeout_mclks =3D ((timeout_us << 12) + (macro_period_us>>1)) / macro_pe= riod_us; + + return timeout_mclks; +} + +uint16_t VL53LX_encode_timeout(uint32_t timeout_mclks) +{ + uint16_t encoded_timeout =3D 0; + uint32_t ls_byte =3D 0; + uint16_t ms_byte =3D 0; + + if (timeout_mclks > 0) { + ls_byte =3D timeout_mclks - 1; + while ((ls_byte & 0xFFFFFF00) > 0) { + ls_byte =3D ls_byte >> 1; + ms_byte++; + } + encoded_timeout =3D (ms_byte << 8) + (uint16_t) (ls_byte & 0x000000FF); + } + return encoded_timeout; +} + + +uint16_t VL53LX_calc_encoded_timeout(uint32_t timeout_us, uint32_t macro_p= eriod_us) +{ + uint32_t timeout_mclks =3D 0; + uint16_t timeout_encoded =3D 0; + + timeout_mclks =3D VL53LX_calc_timeout_mclks(timeout_us, macro_period_us); + + timeout_encoded =3D VL53LX_encode_timeout(timeout_mclks); + + return timeout_encoded; +} + +VL53LX_Error VL53LX_calc_timeout_register_values(uint32_t phasecal_config_= timeout_us, uint32_t mm_config_timeout_us, uint32_t range_config_timeout_us= , uint16_t fast_osc_frequency, VL53LX_general_config_t *pgeneral, VL53LX_ti= ming_config_t *ptiming) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + uint32_t macro_period_us =3D 0; + uint32_t timeout_mclks =3D 0; + uint16_t timeout_encoded =3D 0; + + if (fast_osc_frequency =3D=3D 0) { + status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + } else { + macro_period_us =3D VL53LX_calc_macro_period_us(fast_osc_frequency, ptim= ing->range_config__vcsel_period_a); + + timeout_mclks =3D VL53LX_calc_timeout_mclks(phasecal_config_timeout_us, = macro_period_us); + + if (timeout_mclks > 0xFF) + timeout_mclks =3D 0xFF; + + pgeneral->phasecal_config__timeout_macrop =3D (uint8_t)timeout_mclks; + + timeout_encoded =3D VL53LX_calc_encoded_timeout(mm_config_timeout_us, ma= cro_period_us); + + ptiming->mm_config__timeout_macrop_a_hi =3D (uint8_t)((timeout_encoded &= 0xFF00) >> 8); + ptiming->mm_config__timeout_macrop_a_lo =3D (uint8_t) (timeout_encoded &= 0x00FF); + + timeout_encoded =3D VL53LX_calc_encoded_timeout(range_config_timeout_us,= macro_period_us); + + ptiming->range_config__timeout_macrop_a_hi =3D (uint8_t)((timeout_encode= d & 0xFF00) >> 8); + ptiming->range_config__timeout_macrop_a_lo =3D (uint8_t) (timeout_encode= d & 0x00FF); + + macro_period_us =3D VL53LX_calc_macro_period_us(fast_osc_frequency, ptim= ing->range_config__vcsel_period_b); + + timeout_encoded =3D VL53LX_calc_encoded_timeout(mm_config_timeout_us, ma= cro_period_us); + + ptiming->mm_config__timeout_macrop_b_hi =3D (uint8_t)((timeout_encoded &= 0xFF00) >> 8); + ptiming->mm_config__timeout_macrop_b_lo =3D (uint8_t) (timeout_encoded &= 0x00FF); + + timeout_encoded =3D VL53LX_calc_encoded_timeout(range_config_timeout_us,= macro_period_us); + + ptiming->range_config__timeout_macrop_b_hi =3D (uint8_t)((timeout_encode= d & 0xFF00) >> 8); + ptiming->range_config__timeout_macrop_b_lo =3D (uint8_t) (timeout_encode= d & 0x00FF); + } + return status; +} + +VL53LX_Error VL53LX_set_timeouts_us(VL53LX_DEV Dev, uint32_t phasecal_conf= ig_timeout_us, uint32_t mm_config_timeout_us, uint32_t range_config_timeout= _us) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + if (pdev->stat_nvm.osc_measured__fast_osc__frequency =3D=3D 0) + status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + + if (status =3D=3D VL53LX_ERROR_NONE) { + pdev->phasecal_config_timeout_us =3D phasecal_config_timeout_us; + pdev->mm_config_timeout_us =3D mm_config_timeout_us; + pdev->range_config_timeout_us =3D range_config_timeout_us; + + status =3D VL53LX_calc_timeout_register_values(phasecal_config_timeout_u= s, mm_config_timeout_us, range_config_timeout_us, pdev->stat_nvm.osc_measur= ed__fast_osc__frequency, &(pdev->gen_cfg), &(pdev->tim_cfg)); + } + return status; +} + +static int IsL4(VL53LX_DEV Dev) +{ + int devL4 =3D 0; + VL53LX_LLDriverData_t *pDev; + pDev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + if ((pDev->nvm_copy_data.identification__module_type =3D=3D 0xAA) && (pDe= v->nvm_copy_data.identification__model_id =3D=3D 0xEB)) + devL4 =3D 1; + return devL4; +} + +VL53LX_Error VL53LX_SetMeasurementTimingBudgetMicroSeconds(VL53LX_DEV Dev,= uint32_t MeasurementTimingBudgetMicroSeconds) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + uint32_t TimingGuard; + uint32_t divisor; + uint32_t TimingBudget =3D 0; + uint32_t MmTimeoutUs =3D 0; + uint32_t PhaseCalTimeoutUs =3D 0; + uint32_t FDAMaxTimingBudgetUs =3D FDA_MAX_TIMING_BUDGET_US; + + if (MeasurementTimingBudgetMicroSeconds > 10000000) + Status =3D VL53LX_ERROR_INVALID_PARAMS; + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_get_timeouts_us(Dev, &PhaseCalTimeoutUs, &MmTimeoutUs,= &TimingBudget); + + TimingGuard =3D 1700; + divisor =3D 6; + + if (IsL4(Dev)) + FDAMaxTimingBudgetUs =3D L4_FDA_MAX_TIMING_BUDGET_US; + + if (MeasurementTimingBudgetMicroSeconds <=3D TimingGuard) + Status =3D VL53LX_ERROR_INVALID_PARAMS; + else { + TimingBudget =3D (MeasurementTimingBudgetMicroSeconds - TimingGuard); + } + + if (Status =3D=3D VL53LX_ERROR_NONE) { + if (TimingBudget > FDAMaxTimingBudgetUs) + Status =3D VL53LX_ERROR_INVALID_PARAMS; + else { + TimingBudget /=3D divisor; + Status =3D VL53LX_set_timeouts_us(Dev, PhaseCalTimeoutUs, MmTimeoutUs, = TimingBudget); + } + if (Status =3D=3D VL53LX_ERROR_NONE) + VL53LXDevDataSet(Dev, LLData.range_config_timeout_us, TimingBudget); + } + if (Status =3D=3D VL53LX_ERROR_NONE) { + VL53LXDevDataSet(Dev, CurrentParameters.MeasurementTimingBudgetMicroSeco= nds, MeasurementTimingBudgetMicroSeconds); + } + return Status; +} + +static int store_last_error(struct stmvl53lx_data *data, int rc) +{ + data->last_error =3D rc; + + return -EIO; +} + +VL53LX_Error VL53LX_i2c_encode_system_control(VL53LX_system_control_t *pda= ta, uint16_t buf_size, uint8_t *pbuffer) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + *(pbuffer + 0) =3D pdata->power_management__go1_power_force & 0x1; + *(pbuffer + 1) =3D pdata->system__stream_count_ctrl & 0x1; + *(pbuffer + 2) =3D pdata->firmware__enable & 0x1; + *(pbuffer + 3) =3D pdata->system__interrupt_clear & 0x3; + *(pbuffer + 4) =3D pdata->system__mode_start; + + return status; +} + +VL53LX_Error VL53LX_WriteMulti(VL53LX_DEV pdev, uint16_t index, uint8_t *p= data, uint32_t count) +{ + uint32_t chunk_size =3D WRITE_MULTIPLE_CHUNK_MAX; + VL53LX_Error status; + uint32_t i; + uint16_t hostaddr =3D index; + struct stmvl53lx_data *dev; + + dev =3D (struct stmvl53lx_data *)container_of(pdev, struct stmvl53lx_data= , stdev); + + for (i =3D 0; i < count; i +=3D chunk_size) { + status =3D (cci_write(dev, hostaddr, &pdata[i], min(chunk_size, (count = - i))) ? VL53LX_ERROR_CONTROL_INTERFACE : VL53LX_ERROR_NONE); + if (status !=3D VL53LX_ERROR_NONE) + break; + hostaddr +=3D chunk_size; + } + return status; +} + +VL53LX_Error VL53LX_ReadMulti(VL53LX_DEV pdev, uint16_t index, uint8_t *pd= ata, uint32_t count) +{ + struct stmvl53lx_data *dev; + + dev =3D (struct stmvl53lx_data *)container_of(pdev, struct stmvl53lx_data= , stdev); + + return cci_read(dev, index, pdata, count) ? VL53LX_ERROR_CONTROL_INTERFAC= E : VL53LX_ERROR_NONE; +} + +VL53LX_Error VL53LX_RdByte(VL53LX_DEV pdev, uint16_t index, uint8_t *pdata) +{ + struct stmvl53lx_data *dev; + dev =3D (struct stmvl53lx_data *)container_of(pdev, struct stmvl53lx_data= , stdev); + + return cci_read(dev, index, pdata, 1) ? VL53LX_ERROR_CONTROL_INTERFACE : = VL53LX_ERROR_NONE; +} + +VL53LX_Error VL53LX_WrByte(VL53LX_DEV pdev, uint16_t index, uint8_t data) +{ + struct stmvl53lx_data *dev; + dev =3D (struct stmvl53lx_data *)container_of(pdev, struct stmvl53lx_data= , stdev); + + return cci_write(dev, index, &data, 1); +} + +VL53LX_Error VL53LX_RdWord(VL53LX_DEV pdev, uint16_t index, uint16_t *pdat= a) +{ + VL53LX_Error status; + uint8_t buffer[2]; + + status =3D VL53LX_ReadMulti(pdev, index, buffer, 2); + + *pdata =3D ((uint16_t) buffer[0] << 8) + (uint16_t) buffer[1]; + + return status; +} + +VL53LX_Error VL53LX_WrWord(VL53LX_DEV pdev, uint16_t index, uint16_t data) +{ + VL53LX_Error status; + uint8_t buffer[2]; + + + buffer[0] =3D (uint8_t) (data >> 8); + buffer[1] =3D (uint8_t) (data & 0x00FF); + i2c_debug(" @%x d=3D %x =3D> [ %x , %x ] ", index, data, buffer[0], buff= er[1]); + status =3D VL53LX_WriteMulti(pdev, index, buffer, 2); + + return status; +} + +VL53LX_Error VL53LX_WrDWord(VL53LX_DEV pdev, uint16_t index, uint32_t data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t buffer[4]; + + buffer[0] =3D (uint8_t) (data >> 24); + buffer[1] =3D (uint8_t) ((data & 0x00FF0000) >> 16); + buffer[2] =3D (uint8_t) ((data & 0x0000FF00) >> 8); + buffer[3] =3D (uint8_t) (data & 0x000000FF); + + status =3D VL53LX_WriteMulti(pdev, index, buffer, 4); + + return status; +} + +VL53LX_Error VL53LX_RdDWord(VL53LX_DEV pdev, uint16_t index, uint32_t *pda= ta) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t buffer[4]; + + status =3D VL53LX_ReadMulti(pdev, index, buffer, 4); + + *pdata =3D ((uint32_t) buffer[0] << 24) + ((uint32_t) buffer[1] << 16) + = ((uint32_t) buffer[2] << 8) + (uint32_t) buffer[3]; + + return status; +} + +VL53LX_Error VL53LX_set_system_control(VL53LX_DEV Dev, VL53LX_system_contr= ol_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES]; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_i2c_encode_system_control(pdata, VL53LX_SYSTEM_CONTROL= _I2C_SIZE_BYTES, comms_buffer); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WriteMulti(Dev, VL53LX_POWER_MANAGEMENT__GO1_POWER_FOR= CE, comms_buffer, VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES); + + return status; +} + +void V53L1_init_zone_results_structure(uint8_t active_zones, VL53LX_zone_r= esults_t *pdata) +{ + uint8_t z =3D 0; + VL53LX_zone_objects_t *pobjects; + + pdata->max_zones =3D VL53LX_MAX_USER_ZONES; + pdata->active_zones =3D active_zones; + + for (z =3D 0; z < pdata->max_zones; z++) { + pobjects =3D &(pdata->VL53LX_p_003[z]); + pobjects->cfg_device_state =3D VL53LX_DEVICESTATE_SW_STANDBY; + pobjects->rd_device_state =3D VL53LX_DEVICESTATE_SW_STANDBY; + pobjects->max_objects =3D VL53LX_MAX_RANGE_RESULTS; + pobjects->active_objects =3D 0; + } +} + +void V53L1_init_zone_dss_configs(VL53LX_DEV Dev) +{ + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev); + uint8_t z =3D 0; + uint8_t max_zones =3D VL53LX_MAX_USER_ZONES; + VL53LX_zone_private_dyn_cfgs_t *pdata =3D &(pres->zone_dyn_cfgs); + + for (z =3D 0; z < max_zones; z++) { + pdata->VL53LX_p_003[z].dss_mode =3D VL53LX_DSS_CONTROL__MODE_TARGET_RATE; + pdata->VL53LX_p_003[z].dss_requested_effective_spad_count =3D 0; + } +} + +VL53LX_Error VL53LX_low_power_auto_data_stop_range(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->low_power_auto_data.low_power_auto_range_count =3D 0xFF; + + pdev->low_power_auto_data.first_run_phasecal_result =3D 0; + pdev->low_power_auto_data.dss__total_rate_per_spad_mcps =3D 0; + pdev->low_power_auto_data.dss__required_spads =3D 0; + + if (pdev->low_power_auto_data.saved_vhv_init !=3D 0) + pdev->stat_nvm.vhv_config__init =3D pdev->low_power_auto_data.saved_vhv_= init; + if (pdev->low_power_auto_data.saved_vhv_timeout !=3D 0) + pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =3D pdev->low_power= _auto_data.saved_vhv_timeout; + + pdev->gen_cfg.phasecal_config__override =3D 0x00; + + return status; +} + +VL53LX_Error VL53LX_stop_range(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev); + + pdev->sys_ctrl.system__mode_start =3D (pdev->sys_ctrl.system__mode_start = & VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK) | VL53LX_DEVICEMEASUREMENTMODE_AB= ORT; + + status =3D VL53LX_set_system_control(Dev, &pdev->sys_ctrl); + + pdev->sys_ctrl.system__mode_start =3D (pdev->sys_ctrl.system__mode_start = & VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK); + + VL53LX_init_ll_driver_state(Dev, VL53LX_DEVICESTATE_SW_STANDBY); + + V53L1_init_zone_results_structure(pdev->zone_cfg.active_zones+1, &(pres->= zone_results)); + + V53L1_init_zone_dss_configs(Dev); + + if (pdev->low_power_auto_data.is_low_power_auto_mode =3D=3D 1) + VL53LX_low_power_auto_data_stop_range(Dev); + + return status; +} + +VL53LX_Error VL53LX_set_powerforce_register(VL53LX_DEV Dev, uint8_t value) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->sys_ctrl.power_management__go1_power_force =3D value; + + status =3D VL53LX_WrByte(Dev, VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE, p= dev->sys_ctrl.power_management__go1_power_force); + + return status; +} + +VL53LX_Error VL53LX_disable_powerforce(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + status =3D VL53LX_set_powerforce_register(Dev, 0x00); + + return status; +} + +VL53LX_Error VL53LX_unload_patch(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x00); + + if (status =3D=3D VL53LX_ERROR_NONE) + VL53LX_disable_powerforce(Dev); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_PATCH__CTRL, 0x00); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x01); + + return status; +} + +VL53LX_Error VL53LX_StopMeasurement(VL53LX_DEV Dev) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + Status =3D VL53LX_stop_range(Dev); + + VL53LX_unload_patch(Dev); + + return Status; +} + +static void empty_and_free_list(struct list_head *head) +{ + struct stmvl53lx_waiters *waiter; + struct stmvl53lx_waiters *tmp; + + list_for_each_entry_safe(waiter, tmp, head, list) { + list_del(&waiter->list); + kfree(waiter); + } +} + +static void wake_up_data_waiters(struct stmvl53lx_data *data) +{ + empty_and_free_list(&data->simple_data_reader_list); + empty_and_free_list(&data->mz_data_reader_list); + wake_up(&data->waiter_for_data); +} + +static int stmvl53lx_stop(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + rc =3D VL53LX_StopMeasurement(&data->stdev); + if (rc) { + vl53lx_errmsg("VL53LX_StopMeasurement @%d fail %d", __LINE__, rc); + rc =3D store_last_error(data, rc); + } + + reset_hold(data); + data->enable_sensor =3D 0; + if (data->poll_mode) { + cancel_delayed_work(&data->dwork); + } + + wake_up_data_waiters(data); + return rc; +} + +void VL53LX_i2c_encode_uint16_t(uint16_t ip_value, uint16_t count, uint8_t= *pbuffer) +{ + uint16_t i =3D 0; + uint16_t VL53LX_p_003 =3D 0; + + VL53LX_p_003 =3D ip_value; + + for (i =3D 0; i < count; i++) { + pbuffer[count-i-1] =3D (uint8_t)(VL53LX_p_003 & 0x00FF); + VL53LX_p_003 =3D VL53LX_p_003 >> 8; + } +} + +uint16_t VL53LX_i2c_decode_uint16_t(uint16_t count, uint8_t *pbuffer) +{ + uint16_t value =3D 0x00; + + while (count-- > 0) + value =3D (value << 8) | (uint16_t)*pbuffer++; + + return value; +} + +void VL53LX_i2c_encode_int16_t(int16_t ip_value, uint16_t count, uint8_t *= pbuffer) +{ + uint16_t i =3D 0; + int16_t VL53LX_p_003 =3D 0; + + VL53LX_p_003 =3D ip_value; + + for (i =3D 0; i < count; i++) { + pbuffer[count-i-1] =3D (uint8_t)(VL53LX_p_003 & 0x00FF); + VL53LX_p_003 =3D VL53LX_p_003 >> 8; + } +} + +int16_t VL53LX_i2c_decode_int16_t(uint16_t count, uint8_t *pbuffer) +{ + int16_t value =3D 0x00; + + if (*pbuffer >=3D 0x80) + value =3D 0xFFFF; + + while (count-- > 0) + value =3D (value << 8) | (int16_t)*pbuffer++; + + return value; +} + +uint32_t VL53LX_i2c_decode_with_mask(uint16_t count, uint8_t *pbuffer, uin= t32_t bit_mask, uint32_t down_shift, uint32_t offset) +{ + uint32_t value =3D 0x00; + + while (count-- > 0) + value =3D (value << 8) | (uint32_t)*pbuffer++; + + value =3D value & bit_mask; + if (down_shift > 0) + value =3D value >> down_shift; + + value =3D value + offset; + + return value; +} + + +void VL53LX_i2c_encode_int32_t(int32_t ip_value, uint16_t count, uint8_t *= pbuffer) +{ + uint16_t i =3D 0; + int32_t VL53LX_p_003 =3D 0; + + VL53LX_p_003 =3D ip_value; + + for (i =3D 0; i < count; i++) { + pbuffer[count-i-1] =3D (uint8_t)(VL53LX_p_003 & 0x00FF); + VL53LX_p_003 =3D VL53LX_p_003 >> 8; + } +} + +int32_t VL53LX_i2c_decode_int32_t(uint16_t count, uint8_t *pbuffer) +{ + int32_t value =3D 0x00; + + if (*pbuffer >=3D 0x80) + value =3D 0xFFFFFFFF; + + while (count-- > 0) + value =3D (value << 8) | (int32_t)*pbuffer++; + + return value; +} + +VL53LX_Error VL53LX_i2c_encode_customer_nvm_managed(VL53LX_customer_nvm_ma= naged_t *pdata, uint16_t buf_size, uint8_t *pbuffer) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + *(pbuffer + 0) =3D pdata->global_config__spad_enables_ref_0; + *(pbuffer + 1) =3D pdata->global_config__spad_enables_ref_1; + *(pbuffer + 2) =3D pdata->global_config__spad_enables_ref_2; + *(pbuffer + 3) =3D pdata->global_config__spad_enables_ref_3; + *(pbuffer + 4) =3D pdata->global_config__spad_enables_ref_4; + *(pbuffer + 5) =3D pdata->global_config__spad_enables_ref_5 & 0xF; + *(pbuffer + 6) =3D pdata->global_config__ref_en_start_select; + *(pbuffer + 7) =3D pdata->ref_spad_man__num_requested_ref_spads & 0x3F; + *(pbuffer + 8) =3D pdata->ref_spad_man__ref_location & 0x3; + VL53LX_i2c_encode_uint16_t(pdata->algo__crosstalk_compensation_plane_offs= et_kcps, 2, pbuffer + 9); + VL53LX_i2c_encode_int16_t(pdata->algo__crosstalk_compensation_x_plane_gra= dient_kcps, 2, pbuffer + 11); + VL53LX_i2c_encode_int16_t(pdata->algo__crosstalk_compensation_y_plane_gra= dient_kcps, 2, pbuffer + 13); + VL53LX_i2c_encode_uint16_t(pdata->ref_spad_char__total_rate_target_mcps, = 2, pbuffer + 15); + VL53LX_i2c_encode_int16_t(pdata->algo__part_to_part_range_offset_mm & 0x1= FFF, 2, pbuffer + 17); + VL53LX_i2c_encode_int16_t(pdata->mm_config__inner_offset_mm, 2, pbuffer += 19); + VL53LX_i2c_encode_int16_t(pdata->mm_config__outer_offset_mm, 2, pbuffer += 21); + + return status; +} + +VL53LX_Error VL53LX_set_customer_nvm_managed(VL53LX_DEV Dev, VL53LX_custom= er_nvm_managed_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES]; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_i2c_encode_customer_nvm_managed(pdata, VL53LX_CUSTOMER= _NVM_MANAGED_I2C_SIZE_BYTES, comms_buffer); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WriteMulti(Dev, VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF= _0, comms_buffer, VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES); + + return status; +} + +VL53LX_Error VL53LX_disable_xtalk_compensation(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_hist_post_process_config_t *pHP =3D &(pdev->histpostprocess); + VL53LX_customer_nvm_managed_t *pN =3D &(pdev->customer); + + pN->algo__crosstalk_compensation_plane_offset_kcps =3D 0x00; + pN->algo__crosstalk_compensation_x_plane_gradient_kcps =3D 0x00; + pN->algo__crosstalk_compensation_y_plane_gradient_kcps =3D 0x00; + pdev->xtalk_cfg.global_crosstalk_compensation_enable =3D 0x00; + pHP->algo__crosstalk_compensation_enable =3D pdev->xtalk_cfg.global_cross= talk_compensation_enable; + + if (status =3D=3D VL53LX_ERROR_NONE) { + pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps =3D 0x0000; + } + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_set_customer_nvm_managed(Dev, &(pdev->customer)); + } + return status; +} + +uint32_t VL53LX_calc_crosstalk_plane_offset_with_margin(uint32_t plane_off= set_kcps, int16_t margin_offset_kcps) +{ + uint32_t plane_offset_with_margin =3D 0; + int32_t plane_offset_kcps_temp =3D 0; + + plane_offset_kcps_temp =3D (int32_t)plane_offset_kcps + (int32_t)margin_o= ffset_kcps; + + if (plane_offset_kcps_temp < 0) + plane_offset_kcps_temp =3D 0; + else + if (plane_offset_kcps_temp > 0x3FFFF) + plane_offset_kcps_temp =3D 0x3FFFF; + + plane_offset_with_margin =3D (uint32_t) plane_offset_kcps_temp; + + return plane_offset_with_margin; +} + +uint16_t VL53LX_calc_range_ignore_threshold(uint32_t central_rate, int16_t= x_gradient, int16_t y_gradient, uint8_t rate_mult) +{ + int32_t range_ignore_thresh_int =3D 0; + uint16_t range_ignore_thresh_kcps =3D 0; + int32_t central_rate_int =3D 0; + int16_t x_gradient_int =3D 0; + int16_t y_gradient_int =3D 0; + + central_rate_int =3D ((int32_t)central_rate * (1 << 4)) / (1000); + + if (x_gradient < 0) + x_gradient_int =3D x_gradient * -1; + + if (y_gradient < 0) + y_gradient_int =3D y_gradient * -1; + + + range_ignore_thresh_int =3D (8 * x_gradient_int * 4) + (8 * y_gradient_in= t * 4); + range_ignore_thresh_int =3D range_ignore_thresh_int / 1000; + range_ignore_thresh_int =3D range_ignore_thresh_int + central_rate_int; + range_ignore_thresh_int =3D (int32_t)rate_mult * range_ignore_thresh_int; + range_ignore_thresh_int =3D (range_ignore_thresh_int + (1<<4)) / (1<<5); + + if (range_ignore_thresh_int > 0xFFFF) + range_ignore_thresh_kcps =3D 0xFFFF; + else + range_ignore_thresh_kcps =3D (uint16_t)range_ignore_thresh_int; + + return range_ignore_thresh_kcps; +} + +VL53LX_Error VL53LX_enable_xtalk_compensation(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint32_t tempu32; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_xtalk_config_t *pC =3D &(pdev->xtalk_cfg); + VL53LX_hist_post_process_config_t *pHP =3D &(pdev->histpostprocess); + VL53LX_customer_nvm_managed_t *pN =3D &(pdev->customer); + + tempu32 =3D VL53LX_calc_crosstalk_plane_offset_with_margin(pC->algo__cros= stalk_compensation_plane_offset_kcps, pC->lite_mode_crosstalk_margin_kcps); + if (tempu32 > 0xFFFF) + tempu32 =3D 0xFFFF; + + pN->algo__crosstalk_compensation_plane_offset_kcps =3D (uint16_t)tempu32; + pN->algo__crosstalk_compensation_x_plane_gradient_kcps =3D pC->algo__cros= stalk_compensation_x_plane_gradient_kcps; + pN->algo__crosstalk_compensation_y_plane_gradient_kcps =3D pC->algo__cros= stalk_compensation_y_plane_gradient_kcps; + pHP->algo__crosstalk_compensation_plane_offset_kcps =3D VL53LX_calc_cross= talk_plane_offset_with_margin(pC->algo__crosstalk_compensation_plane_offset= _kcps, pC->histogram_mode_crosstalk_margin_kcps); + pHP->algo__crosstalk_compensation_x_plane_gradient_kcps =3D pC->algo__cro= sstalk_compensation_x_plane_gradient_kcps; + pHP->algo__crosstalk_compensation_y_plane_gradient_kcps =3D pC->algo__cro= sstalk_compensation_y_plane_gradient_kcps; + pC->global_crosstalk_compensation_enable =3D 0x01; + pHP->algo__crosstalk_compensation_enable =3D pC->global_crosstalk_compens= ation_enable; + + if (status =3D=3D VL53LX_ERROR_NONE) { + pC->crosstalk_range_ignore_threshold_rate_mcps =3D + VL53LX_calc_range_ignore_threshold(pC->algo__crosstalk_compensation_plan= e_offset_kcps, pC->algo__crosstalk_compensation_x_plane_gradient_kcps, pC->= algo__crosstalk_compensation_y_plane_gradient_kcps, pC->crosstalk_range_ign= ore_threshold_mult); + } + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_set_customer_nvm_managed(Dev, &(pdev->customer)); + + return status; +} + +VL53LX_Error VL53LX_SetXTalkCompensationEnable(VL53LX_DEV Dev, uint8_t XTa= lkCompensationEnable) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + if (XTalkCompensationEnable =3D=3D 0) + Status =3D VL53LX_disable_xtalk_compensation(Dev); + else + Status =3D VL53LX_enable_xtalk_compensation(Dev); + + return Status; +} + +static VL53LX_Error ComputeDevicePresetMode(VL53LX_DistanceModes DistanceM= ode, VL53LX_DevicePresetModes *pDevicePresetMode) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + uint8_t DistIdx; + VL53LX_DevicePresetModes RangingModes[3] =3D { VL53LX_DEVICEPRESETMODE_HI= STOGRAM_SHORT_RANGE, VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE, VL53LX= _DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE}; + + switch (DistanceMode) { + case VL53LX_DISTANCEMODE_SHORT: + DistIdx =3D 0; + break; + case VL53LX_DISTANCEMODE_MEDIUM: + DistIdx =3D 1; + break; + default: + DistIdx =3D 2; + } + *pDevicePresetMode =3D RangingModes[DistIdx]; + return Status; +} + +VL53LX_Error VL53LX_get_preset_mode_timing_cfg(VL53LX_DEV Dev, VL53LX_Devi= cePresetModes device_preset_mode, uint16_t *pdss_config__target_total_rate_= mcps, uint32_t *pphasecal_config_timeout_us, uint32_t *pmm_config_timeout_u= s, uint32_t *prange_config_timeout_us) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + switch (device_preset_mode) { + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE: + *pdss_config__target_total_rate_mcps =3D pdev->tuning_parms.tp_dss_targe= t_histo_mcps; + *pphasecal_config_timeout_us =3D pdev->tuning_parms.tp_phasecal_timeout_= hist_long_us; + *pmm_config_timeout_us =3D pdev->tuning_parms.tp_mm_timeout_histo_us; + *prange_config_timeout_us =3D pdev->tuning_parms.tp_range_timeout_histo_= us; + break; + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE: + *pdss_config__target_total_rate_mcps =3D pdev->tuning_parms.tp_dss_targe= t_histo_mcps; + *pphasecal_config_timeout_us =3D pdev->tuning_parms.tp_phasecal_timeout_= hist_med_us; + *pmm_config_timeout_us =3D pdev->tuning_parms.tp_mm_timeout_histo_us; + *prange_config_timeout_us =3D pdev->tuning_parms.tp_range_timeout_histo_= us; + break; + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE: + *pdss_config__target_total_rate_mcps =3D pdev->tuning_parms.tp_dss_targe= t_histo_mcps; + *pphasecal_config_timeout_us =3D pdev->tuning_parms.tp_phasecal_timeout_= hist_short_us; + *pmm_config_timeout_us =3D pdev->tuning_parms.tp_mm_timeout_histo_us; + *prange_config_timeout_us =3D pdev->tuning_parms.tp_range_timeout_histo_= us; + break; + default: + status =3D VL53LX_ERROR_INVALID_PARAMS; + break; + } + + return status; +} + +VL53LX_Error VL53LX_preset_mode_standard_ranging( + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pstatic->dss_config__target_total_rate_mcps =3D 0x0A00; + pstatic->debug__ctrl =3D 0x00; + pstatic->test_mode__ctrl =3D 0x00; + pstatic->clk_gating__ctrl =3D 0x00; + pstatic->nvm_bist__ctrl =3D 0x00; + pstatic->nvm_bist__num_nvm_words =3D 0x00; + pstatic->nvm_bist__start_address =3D 0x00; + pstatic->host_if__status =3D 0x00; + pstatic->pad_i2c_hv__config =3D 0x00; + pstatic->pad_i2c_hv__extsup_config =3D 0x00; + pstatic->gpio_hv_pad__ctrl =3D 0x00; + pstatic->gpio_hv_mux__ctrl =3D VL53LX_DEVICEINTERRUPTPOLARITY_ACTIVE_LOW = | VL53LX_DEVICEGPIOMODE_OUTPUT_RANGE_AND_ERROR_INTERRUPTS; + pstatic->gpio__tio_hv_status =3D 0x02; + pstatic->gpio__fio_hv_status =3D 0x00; + pstatic->ana_config__spad_sel_pswidth =3D 0x02; + pstatic->ana_config__vcsel_pulse_width_offset =3D 0x08; + pstatic->ana_config__fast_osc__config_ctrl =3D 0x00; + pstatic->sigma_estimator__effective_pulse_width_ns =3D ptuning_parms->tp_= lite_sigma_est_pulse_width_ns; + pstatic->sigma_estimator__effective_ambient_width_ns =3D ptuning_parms->t= p_lite_sigma_est_amb_width_ns; + pstatic->sigma_estimator__sigma_ref_mm =3D ptuning_parms->tp_lite_sigma_r= ef_mm; + pstatic->algo__crosstalk_compensation_valid_height_mm =3D 0x01; + pstatic->spare_host_config__static_config_spare_0 =3D 0x00; + pstatic->spare_host_config__static_config_spare_1 =3D 0x00; + pstatic->algo__range_ignore_threshold_mcps =3D 0x0000; + pstatic->algo__range_ignore_valid_height_mm =3D 0xff; + pstatic->algo__range_min_clip =3D ptuning_parms->tp_lite_min_clip; + pstatic->algo__consistency_check__tolerance =3D ptuning_parms->tp_consist= ency_lite_phase_tolerance; + pstatic->spare_host_config__static_config_spare_2 =3D 0x00; + pstatic->sd_config__reset_stages_msb =3D 0x00; + pstatic->sd_config__reset_stages_lsb =3D 0x00; + pgeneral->gph_config__stream_count_update_value =3D 0x00; + pgeneral->global_config__stream_divider =3D 0x00; + pgeneral->system__interrupt_config_gpio =3D VL53LX_INTERRUPT_CONFIG_NEW_S= AMPLE_READY; + pgeneral->cal_config__vcsel_start =3D 0x0B; + pgeneral->cal_config__repeat_rate =3D ptuning_parms->tp_cal_repeat_rate; + pgeneral->global_config__vcsel_width =3D 0x02; + pgeneral->phasecal_config__timeout_macrop =3D 0x0D; + pgeneral->phasecal_config__target =3D ptuning_parms->tp_phasecal_target; + pgeneral->phasecal_config__override =3D 0x00; + pgeneral->dss_config__roi_mode_control =3D VL53LX_DEVICEDSSMODE__TARGET_R= ATE; + pgeneral->system__thresh_rate_high =3D 0x0000; + pgeneral->system__thresh_rate_low =3D 0x0000; + pgeneral->dss_config__manual_effective_spads_select =3D 0x8C00; + pgeneral->dss_config__manual_block_select =3D 0x00; + pgeneral->dss_config__aperture_attenuation =3D 0x38; + pgeneral->dss_config__max_spads_limit =3D 0xFF; + pgeneral->dss_config__min_spads_limit =3D 0x01; + ptiming->mm_config__timeout_macrop_a_hi =3D 0x00; + ptiming->mm_config__timeout_macrop_a_lo =3D 0x1a; + ptiming->mm_config__timeout_macrop_b_hi =3D 0x00; + ptiming->mm_config__timeout_macrop_b_lo =3D 0x20; + ptiming->range_config__timeout_macrop_a_hi =3D 0x01; + ptiming->range_config__timeout_macrop_a_lo =3D 0xCC; + ptiming->range_config__vcsel_period_a =3D 0x0B; + ptiming->range_config__timeout_macrop_b_hi =3D 0x01; + ptiming->range_config__timeout_macrop_b_lo =3D 0xF5; + ptiming->range_config__vcsel_period_b =3D 0x09; + ptiming->range_config__sigma_thresh =3D ptuning_parms->tp_lite_med_sigma_= thresh_mm; + ptiming->range_config__min_count_rate_rtn_limit_mcps =3D ptuning_parms->t= p_lite_med_min_count_rate_rtn_mcps; + ptiming->range_config__valid_phase_low =3D 0x08; + ptiming->range_config__valid_phase_high =3D 0x78; + ptiming->system__intermeasurement_period =3D 0x00000000; + ptiming->system__fractional_enable =3D 0x00; + phistogram->histogram_config__low_amb_even_bin_0_1 =3D 0x07; + phistogram->histogram_config__low_amb_even_bin_2_3 =3D 0x21; + phistogram->histogram_config__low_amb_even_bin_4_5 =3D 0x43; + phistogram->histogram_config__low_amb_odd_bin_0_1 =3D 0x10; + phistogram->histogram_config__low_amb_odd_bin_2_3 =3D 0x32; + phistogram->histogram_config__low_amb_odd_bin_4_5 =3D 0x54; + phistogram->histogram_config__mid_amb_even_bin_0_1 =3D 0x07; + phistogram->histogram_config__mid_amb_even_bin_2_3 =3D 0x21; + phistogram->histogram_config__mid_amb_even_bin_4_5 =3D 0x43; + phistogram->histogram_config__mid_amb_odd_bin_0_1 =3D 0x10; + phistogram->histogram_config__mid_amb_odd_bin_2 =3D 0x02; + phistogram->histogram_config__mid_amb_odd_bin_3_4 =3D 0x43; + phistogram->histogram_config__mid_amb_odd_bin_5 =3D 0x05; + phistogram->histogram_config__user_bin_offset =3D 0x00; + phistogram->histogram_config__high_amb_even_bin_0_1 =3D 0x07; + phistogram->histogram_config__high_amb_even_bin_2_3 =3D 0x21; + phistogram->histogram_config__high_amb_even_bin_4_5 =3D 0x43; + phistogram->histogram_config__high_amb_odd_bin_0_1 =3D 0x10; + phistogram->histogram_config__high_amb_odd_bin_2_3 =3D 0x32; + phistogram->histogram_config__high_amb_odd_bin_4_5 =3D 0x54; + phistogram->histogram_config__amb_thresh_low =3D 0xFFFF; + phistogram->histogram_config__amb_thresh_high =3D 0xFFFF; + phistogram->histogram_config__spad_array_selection =3D 0x00; + pzone_cfg->max_zones =3D VL53LX_MAX_USER_ZONES; + pzone_cfg->active_zones =3D 0x00; + pzone_cfg->user_zones[0].height =3D 0x0f; + pzone_cfg->user_zones[0].width =3D 0x0f; + pzone_cfg->user_zones[0].x_centre =3D 0x08; + pzone_cfg->user_zones[0].y_centre =3D 0x08; + pdynamic->system__grouped_parameter_hold_0 =3D 0x01; + pdynamic->system__thresh_high =3D 0x0000; + pdynamic->system__thresh_low =3D 0x0000; + pdynamic->system__enable_xtalk_per_quadrant =3D 0x00; + pdynamic->system__seed_config =3D ptuning_parms->tp_lite_seed_cfg; + pdynamic->sd_config__woi_sd0 =3D 0x0B; + pdynamic->sd_config__woi_sd1 =3D 0x09; + pdynamic->sd_config__initial_phase_sd0 =3D ptuning_parms->tp_init_phase_r= tn_lite_med; + pdynamic->sd_config__initial_phase_sd1 =3D ptuning_parms->tp_init_phase_r= ef_lite_med; + pdynamic->system__grouped_parameter_hold_1 =3D 0x01; + pdynamic->sd_config__first_order_select =3D ptuning_parms->tp_lite_first_= order_select; + pdynamic->sd_config__quantifier =3D ptuning_parms->tp_lite_quantifier; + pdynamic->roi_config__user_roi_centre_spad =3D 0xC7; + pdynamic->roi_config__user_roi_requested_global_xy_size =3D 0xFF; + pdynamic->system__sequence_config =3D VL53LX_SEQUENCE_VHV_EN | VL53LX_SEQ= UENCE_PHASECAL_EN | VL53LX_SEQUENCE_DSS1_EN | VL53LX_SEQUENCE_DSS2_EN | VL5= 3LX_SEQUENCE_MM2_EN | VL53LX_SEQUENCE_RANGE_EN; + pdynamic->system__grouped_parameter_hold =3D 0x02; + psystem->system__stream_count_ctrl =3D 0x00; + psystem->firmware__enable =3D 0x01; + psystem->system__interrupt_clear =3D VL53LX_CLEAR_RANGE_INT; + psystem->system__mode_start =3D VL53LX_DEVICESCHEDULERMODE_STREAMING | VL= 53LX_DEVICEREADOUTMODE_SINGLE_SD | VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + + return status; +} + +void VL53LX_init_histogram_config_structure( + uint8_t even_bin0, + uint8_t even_bin1, + uint8_t even_bin2, + uint8_t even_bin3, + uint8_t even_bin4, + uint8_t even_bin5, + uint8_t odd_bin0, + uint8_t odd_bin1, + uint8_t odd_bin2, + uint8_t odd_bin3, + uint8_t odd_bin4, + uint8_t odd_bin5, + VL53LX_histogram_config_t *pdata) +{ + pdata->histogram_config__low_amb_even_bin_0_1 =3D (even_bin1 << 4) + even= _bin0; + pdata->histogram_config__low_amb_even_bin_2_3 =3D (even_bin3 << 4) + even= _bin2; + pdata->histogram_config__low_amb_even_bin_4_5 =3D (even_bin5 << 4) + even= _bin4; + pdata->histogram_config__low_amb_odd_bin_0_1 =3D (odd_bin1 << 4) + odd_bi= n0; + pdata->histogram_config__low_amb_odd_bin_2_3 =3D (odd_bin3 << 4) + odd_bi= n2; + pdata->histogram_config__low_amb_odd_bin_4_5 =3D (odd_bin5 << 4) + odd_bi= n4; + pdata->histogram_config__mid_amb_even_bin_0_1 =3D pdata->histogram_config= __low_amb_even_bin_0_1; + pdata->histogram_config__mid_amb_even_bin_2_3 =3D pdata->histogram_config= __low_amb_even_bin_2_3; + pdata->histogram_config__mid_amb_even_bin_4_5 =3D pdata->histogram_config= __low_amb_even_bin_4_5; + pdata->histogram_config__mid_amb_odd_bin_0_1 =3D pdata->histogram_config_= _low_amb_odd_bin_0_1; + pdata->histogram_config__mid_amb_odd_bin_2 =3D odd_bin2; + pdata->histogram_config__mid_amb_odd_bin_3_4 =3D (odd_bin4 << 4) + odd_bi= n3; + pdata->histogram_config__mid_amb_odd_bin_5 =3D odd_bin5; + pdata->histogram_config__user_bin_offset =3D 0x00; + pdata->histogram_config__high_amb_even_bin_0_1 =3D pdata->histogram_confi= g__low_amb_even_bin_0_1; + pdata->histogram_config__high_amb_even_bin_2_3 =3D pdata->histogram_confi= g__low_amb_even_bin_2_3; + pdata->histogram_config__high_amb_even_bin_4_5 =3D pdata->histogram_confi= g__low_amb_even_bin_4_5; + pdata->histogram_config__high_amb_odd_bin_0_1 =3D pdata->histogram_config= __low_amb_odd_bin_0_1; + pdata->histogram_config__high_amb_odd_bin_2_3 =3D pdata->histogram_config= __low_amb_odd_bin_2_3; + pdata->histogram_config__high_amb_odd_bin_4_5 =3D pdata->histogram_config= __low_amb_odd_bin_4_5; + pdata->histogram_config__amb_thresh_low =3D 0xFFFF; + pdata->histogram_config__amb_thresh_high =3D 0xFFFF; + pdata->histogram_config__spad_array_selection =3D 0x00; +} + +void VL53LX_init_histogram_multizone_config_structure( + uint8_t even_bin0, + uint8_t even_bin1, + uint8_t even_bin2, + uint8_t even_bin3, + uint8_t even_bin4, + uint8_t even_bin5, + uint8_t odd_bin0, + uint8_t odd_bin1, + uint8_t odd_bin2, + uint8_t odd_bin3, + uint8_t odd_bin4, + uint8_t odd_bin5, + VL53LX_histogram_config_t *pdata) +{ + pdata->histogram_config__low_amb_even_bin_0_1 =3D (even_bin1 << 4) + even= _bin0; + pdata->histogram_config__low_amb_even_bin_2_3 =3D (even_bin3 << 4) + even= _bin2; + pdata->histogram_config__low_amb_even_bin_4_5 =3D (even_bin5 << 4) + even= _bin4; + pdata->histogram_config__low_amb_odd_bin_0_1 =3D pdata->histogram_config_= _low_amb_even_bin_0_1; + pdata->histogram_config__low_amb_odd_bin_2_3 =3D pdata->histogram_config_= _low_amb_even_bin_2_3; + pdata->histogram_config__low_amb_odd_bin_4_5 =3D pdata->histogram_config_= _low_amb_even_bin_4_5; + pdata->histogram_config__mid_amb_even_bin_0_1 =3D pdata->histogram_config= __low_amb_even_bin_0_1; + pdata->histogram_config__mid_amb_even_bin_2_3 =3D pdata->histogram_config= __low_amb_even_bin_2_3; + pdata->histogram_config__mid_amb_even_bin_4_5 =3D pdata->histogram_config= __low_amb_even_bin_4_5; + pdata->histogram_config__mid_amb_odd_bin_0_1 =3D pdata->histogram_config_= _low_amb_odd_bin_0_1; + pdata->histogram_config__mid_amb_odd_bin_2 =3D odd_bin2; + pdata->histogram_config__mid_amb_odd_bin_3_4 =3D (odd_bin4 << 4) + odd_bi= n3; + pdata->histogram_config__mid_amb_odd_bin_5 =3D odd_bin5; + pdata->histogram_config__user_bin_offset =3D 0x00; + pdata->histogram_config__high_amb_even_bin_0_1 =3D (odd_bin1 << 4) + odd_= bin0; + pdata->histogram_config__high_amb_even_bin_2_3 =3D (odd_bin3 << 4) + odd_= bin2; + pdata->histogram_config__high_amb_even_bin_4_5 =3D (odd_bin5 << 4) + odd_= bin4; + pdata->histogram_config__high_amb_odd_bin_0_1 =3D pdata->histogram_config= __high_amb_even_bin_0_1; + pdata->histogram_config__high_amb_odd_bin_2_3 =3D pdata->histogram_config= __high_amb_even_bin_2_3; + pdata->histogram_config__high_amb_odd_bin_4_5 =3D pdata->histogram_config= __high_amb_even_bin_4_5; + pdata->histogram_config__amb_thresh_low =3D 0xFFFF; + pdata->histogram_config__amb_thresh_high =3D 0xFFFF; + pdata->histogram_config__spad_array_selection =3D 0x00; +} + +void VL53LX_copy_hist_cfg_to_static_cfg( + VL53LX_histogram_config_t *phistogram, + VL53LX_static_config_t *pstatic, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic) +{ + SUPPRESS_UNUSED_WARNING(pgeneral); + + pstatic->sigma_estimator__effective_pulse_width_ns =3D phistogram->histog= ram_config__high_amb_even_bin_0_1; + pstatic->sigma_estimator__effective_ambient_width_ns =3D phistogram->hist= ogram_config__high_amb_even_bin_2_3; + pstatic->sigma_estimator__sigma_ref_mm =3D phistogram->histogram_config__= high_amb_even_bin_4_5; + pstatic->algo__crosstalk_compensation_valid_height_mm =3D phistogram->his= togram_config__high_amb_odd_bin_0_1; + pstatic->spare_host_config__static_config_spare_0 =3D phistogram->histogr= am_config__high_amb_odd_bin_2_3; + pstatic->spare_host_config__static_config_spare_1 =3D phistogram->histogr= am_config__high_amb_odd_bin_4_5; + pstatic->algo__range_ignore_threshold_mcps =3D (((uint16_t)phistogram->hi= stogram_config__mid_amb_even_bin_0_1) << 8) + (uint16_t)phistogram->histogr= am_config__mid_amb_even_bin_2_3; + pstatic->algo__range_ignore_valid_height_mm =3D phistogram->histogram_con= fig__mid_amb_even_bin_4_5; + pstatic->algo__range_min_clip =3D phistogram->histogram_config__mid_amb_o= dd_bin_0_1; + pstatic->algo__consistency_check__tolerance =3D phistogram->histogram_con= fig__mid_amb_odd_bin_2; + pstatic->spare_host_config__static_config_spare_2 =3D phistogram->histogr= am_config__mid_amb_odd_bin_3_4; + pstatic->sd_config__reset_stages_msb =3D phistogram->histogram_config__mi= d_amb_odd_bin_5; + pstatic->sd_config__reset_stages_lsb =3D phistogram->histogram_config__us= er_bin_offset; + ptiming->range_config__sigma_thresh =3D (((uint16_t)phistogram->histogram= _config__low_amb_even_bin_0_1) << 8) + (uint16_t)phistogram->histogram_conf= ig__low_amb_even_bin_2_3; + ptiming->range_config__min_count_rate_rtn_limit_mcps =3D (((uint16_t)phis= togram->histogram_config__low_amb_even_bin_4_5) << 8) + (uint16_t)phistogra= m->histogram_config__low_amb_odd_bin_0_1; + ptiming->range_config__valid_phase_low =3D phistogram->histogram_config__= low_amb_odd_bin_2_3; + ptiming->range_config__valid_phase_high =3D phistogram->histogram_config_= _low_amb_odd_bin_4_5; + pdynamic->system__thresh_high =3D phistogram->histogram_config__amb_thres= h_low; + pdynamic->system__thresh_low =3D phistogram->histogram_config__amb_thresh= _high; + pdynamic->system__enable_xtalk_per_quadrant =3D phistogram->histogram_con= fig__spad_array_selection; +} + +VL53LX_Error VL53LX_preset_mode_histogram_ranging( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + status =3D VL53LX_preset_mode_standard_ranging(pstatic, phistogram, pgene= ral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cfg); + if (status =3D=3D VL53LX_ERROR_NONE) { + pstatic->dss_config__target_total_rate_mcps =3D 0x1400; + VL53LX_init_histogram_config_structure(7, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, = 5, phistogram); + VL53LX_init_histogram_multizone_config_structure(7, 0, 1, 2, 3, 4, 0, 1,= 2, 3, 4, 5, &(pzone_cfg->multizone_hist_cfg)); + ptiming->range_config__vcsel_period_a =3D 0x09; + ptiming->range_config__vcsel_period_b =3D 0x0B; + pdynamic->sd_config__woi_sd0 =3D 0x09; + pdynamic->sd_config__woi_sd1 =3D 0x0B; + ptiming->mm_config__timeout_macrop_a_hi =3D 0x00; + ptiming->mm_config__timeout_macrop_a_lo =3D 0x20; + ptiming->mm_config__timeout_macrop_b_hi =3D 0x00; + ptiming->mm_config__timeout_macrop_b_lo =3D 0x1A; + ptiming->range_config__timeout_macrop_a_hi =3D 0x00; + ptiming->range_config__timeout_macrop_a_lo =3D 0x28; + ptiming->range_config__timeout_macrop_b_hi =3D 0x00; + ptiming->range_config__timeout_macrop_b_lo =3D 0x21; + pgeneral->phasecal_config__timeout_macrop =3D 0xF5; + phistpostprocess->valid_phase_low =3D 0x08; + phistpostprocess->valid_phase_high =3D 0x88; + VL53LX_copy_hist_cfg_to_static_cfg(phistogram, pstatic, pgeneral, ptimin= g, pdynamic); + pdynamic->system__sequence_config =3D VL53LX_SEQUENCE_VHV_EN | VL53LX_SE= QUENCE_PHASECAL_EN | VL53LX_SEQUENCE_DSS1_EN | VL53LX_SEQUENCE_DSS2_EN | VL= 53LX_SEQUENCE_RANGE_EN; + psystem->system__mode_start =3D VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | V= L53LX_DEVICEREADOUTMODE_DUAL_SD | VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + return status; +} + +VL53LX_Error VL53LX_preset_mode_histogram_long_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + status =3D VL53LX_preset_mode_histogram_ranging(phistpostprocess, pstatic= , phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cf= g); + if (status =3D=3D VL53LX_ERROR_NONE) { + VL53LX_init_histogram_config_structure(7, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, = 5, phistogram); + VL53LX_init_histogram_multizone_config_structure(7, 0, 1, 2, 3, 4, 0, 1,= 2, 3, 4, 5, &(pzone_cfg->multizone_hist_cfg)); + VL53LX_copy_hist_cfg_to_static_cfg(phistogram, pstatic, pgeneral, ptimin= g, pdynamic); + ptiming->range_config__vcsel_period_a =3D 0x09; + ptiming->range_config__vcsel_period_b =3D 0x0b; + ptiming->mm_config__timeout_macrop_a_hi =3D 0x00; + ptiming->mm_config__timeout_macrop_a_lo =3D 0x21; + ptiming->mm_config__timeout_macrop_b_hi =3D 0x00; + ptiming->mm_config__timeout_macrop_b_lo =3D 0x1b; + ptiming->range_config__timeout_macrop_a_hi =3D 0x00; + ptiming->range_config__timeout_macrop_a_lo =3D 0x29; + ptiming->range_config__timeout_macrop_b_hi =3D 0x00; + ptiming->range_config__timeout_macrop_b_lo =3D 0x22; + pgeneral->cal_config__vcsel_start =3D 0x09; + pgeneral->phasecal_config__timeout_macrop =3D 0xF5; + pdynamic->sd_config__woi_sd0 =3D 0x09; + pdynamic->sd_config__woi_sd1 =3D 0x0B; + pdynamic->sd_config__initial_phase_sd0 =3D ptuning_parms->tp_init_phase_= rtn_hist_long; + pdynamic->sd_config__initial_phase_sd1 =3D ptuning_parms->tp_init_phase_= ref_hist_long; + phistpostprocess->valid_phase_low =3D 0x08; + phistpostprocess->valid_phase_high =3D 0x88; + pdynamic->system__sequence_config =3D VL53LX_SEQUENCE_VHV_EN | VL53LX_SE= QUENCE_PHASECAL_EN | VL53LX_SEQUENCE_DSS1_EN | VL53LX_SEQUENCE_DSS2_EN | VL= 53LX_SEQUENCE_RANGE_EN; + psystem->system__mode_start =3D VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | V= L53LX_DEVICEREADOUTMODE_DUAL_SD | VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + return status; +} + +VL53LX_Error VL53LX_set_inter_measurement_period_ms(VL53LX_DEV Dev, uint32= _t inter_measurement_period_ms) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + if (pdev->dbg_results.result__osc_calibrate_val =3D=3D 0) + status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + + if (status =3D=3D VL53LX_ERROR_NONE) { + pdev->inter_measurement_period_ms =3D inter_measurement_period_ms; + pdev->tim_cfg.system__intermeasurement_period =3D inter_measurement_peri= od_ms * (uint32_t)pdev->dbg_results.result__osc_calibrate_val; + } + return status; +} + +VL53LX_Error VL53LX_preset_mode_histogram_medium_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + status =3D VL53LX_preset_mode_histogram_ranging(phistpostprocess, pstatic= , phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cf= g); + + if (status =3D=3D VL53LX_ERROR_NONE) { + VL53LX_init_histogram_config_structure(7, 0, 1, 1, 2, 2, 0, 1, 2, 1, 2, = 3, phistogram); + VL53LX_init_histogram_multizone_config_structure(7, 0, 1, 1, 2, 2, 0, 1,= 2, 1, 2, 3, &(pzone_cfg->multizone_hist_cfg)); + VL53LX_copy_hist_cfg_to_static_cfg(phistogram, pstatic, pgeneral, ptimin= g, pdynamic); + + ptiming->range_config__vcsel_period_a =3D 0x05; + ptiming->range_config__vcsel_period_b =3D 0x07; + + ptiming->mm_config__timeout_macrop_a_hi =3D 0x00; + ptiming->mm_config__timeout_macrop_a_lo =3D 0x36; + ptiming->mm_config__timeout_macrop_b_hi =3D 0x00; + ptiming->mm_config__timeout_macrop_b_lo =3D 0x28; + + ptiming->range_config__timeout_macrop_a_hi =3D 0x00; + ptiming->range_config__timeout_macrop_a_lo =3D 0x44; + ptiming->range_config__timeout_macrop_b_hi =3D 0x00; + ptiming->range_config__timeout_macrop_b_lo =3D 0x33; + + pgeneral->cal_config__vcsel_start =3D 0x05; + + pgeneral->phasecal_config__timeout_macrop =3D 0xF5; + + pdynamic->sd_config__woi_sd0 =3D 0x05; + pdynamic->sd_config__woi_sd1 =3D 0x07; + pdynamic->sd_config__initial_phase_sd0 =3D ptuning_parms->tp_= init_phase_rtn_hist_med; + pdynamic->sd_config__initial_phase_sd1 =3D ptuning_parms->tp_= init_phase_ref_hist_med; + + phistpostprocess->valid_phase_low =3D 0x08; + phistpostprocess->valid_phase_high =3D 0x48; + + pdynamic->system__sequence_config =3D VL53LX_SEQUENCE_VHV_EN | VL53LX_SE= QUENCE_PHASECAL_EN | VL53LX_SEQUENCE_DSS1_EN | VL53LX_SEQUENCE_DSS2_EN | VL= 53LX_SEQUENCE_RANGE_EN; + + psystem->system__mode_start =3D VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | V= L53LX_DEVICEREADOUTMODE_DUAL_SD | VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + return status; +} + + +VL53LX_Error VL53LX_set_preset_mode(VL53LX_DEV Dev, VL53LX_DevicePresetMod= es device_preset_mode, uint16_t dss_config__target_total_rate_mcps, uint32_= t phasecal_config_timeout_us, uint32_t mm_config_timeout_us, uint32_t range= _config_timeout_us, uint32_t inter_measurement_period_ms) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev); + + VL53LX_hist_post_process_config_t *phistpostprocess =3D &(pdev->histpostp= rocess); + + VL53LX_static_config_t *pstatic =3D &(pdev->stat_cfg); + VL53LX_histogram_config_t *phistogram =3D &(pdev->hist_cfg); + VL53LX_general_config_t *pgeneral =3D &(pdev->gen_cfg); + VL53LX_timing_config_t *ptiming =3D &(pdev->tim_cfg); + VL53LX_dynamic_config_t *pdynamic =3D &(pdev->dyn_cfg); + VL53LX_system_control_t *psystem =3D &(pdev->sys_ctrl); + VL53LX_zone_config_t *pzone_cfg =3D &(pdev->zone_cfg); + VL53LX_tuning_parm_storage_t *ptuning_parms =3D &(pdev->tuning_parms); + + pdev->preset_mode =3D device_preset_mode; + pdev->mm_config_timeout_us =3D mm_config_timeout_us; + pdev->range_config_timeout_us =3D range_config_timeout_us; + pdev->inter_measurement_period_ms =3D inter_measurement_period_ms; + + VL53LX_init_ll_driver_state(Dev, VL53LX_DEVICESTATE_SW_STANDBY); + + switch (device_preset_mode) { + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE: + status =3D VL53LX_preset_mode_histogram_long_range(phistpostprocess, pst= atic, phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzon= e_cfg); + break; + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE: + status =3D VL53LX_preset_mode_histogram_medium_range(phistpostprocess, p= static, phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pz= one_cfg); + break; + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE: + status =3D VL53LX_preset_mode_histogram_short_range(phistpostprocess, ps= tatic, phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzo= ne_cfg); + break; + default: + status =3D VL53LX_ERROR_INVALID_PARAMS; + break; + } + if (status =3D=3D VL53LX_ERROR_NONE) { + pstatic->dss_config__target_total_rate_mcps =3D dss_config__target_total= _rate_mcps; + pdev->dss_config__target_total_rate_mcps =3D dss_config__target_total_ra= te_mcps; + } + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_set_timeouts_us(Dev, phasecal_config_timeout_us, mm_co= nfig_timeout_us, range_config_timeout_us); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_set_inter_measurement_period_ms(Dev, inter_measurement= _period_ms); + + V53L1_init_zone_results_structure(pdev->zone_cfg.active_zones+1, &(pres->= zone_results)); + + return status; +} + + +static VL53LX_Error SetPresetModeL3CX(VL53LX_DEV Dev, VL53LX_DistanceModes= DistanceMode, uint32_t inter_measurement_period_ms) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_DevicePresetModes device_preset_mode; + uint8_t measurement_mode; + uint16_t dss_config__target_total_rate_mcps =3D 0; + uint32_t phasecal_config_timeout_us =3D 0; + uint32_t mm_config_timeout_us =3D 0; + uint32_t lld_range_config_timeout_us =3D 0; + + measurement_mode =3D VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + + Status =3D ComputeDevicePresetMode(DistanceMode, &device_preset_mode); + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_get_preset_mode_timing_cfg(Dev, device_preset_mode, &= dss_config__target_total_rate_mcps, &phasecal_config_timeout_us, &mm_config= _timeout_us, &lld_range_config_timeout_us); + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_set_preset_mode(Dev, device_preset_mode, dss_config__t= arget_total_rate_mcps, phasecal_config_timeout_us, mm_config_timeout_us, ll= d_range_config_timeout_us, inter_measurement_period_ms); + + if (Status =3D=3D VL53LX_ERROR_NONE) + VL53LXDevDataSet(Dev, LLData.measurement_mode, measurement_mode); + + return Status; +} + +VL53LX_Error VL53LX_SetDistanceMode(VL53LX_DEV Dev, VL53LX_DistanceModes D= istanceMode) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + uint32_t inter_measurement_period_ms; + uint32_t TimingBudget =3D 0; + uint32_t MmTimeoutUs =3D 0; + uint32_t PhaseCalTimeoutUs =3D 0; + + if ((DistanceMode !=3D VL53LX_DISTANCEMODE_SHORT) && (DistanceMode !=3D V= L53LX_DISTANCEMODE_MEDIUM) && (DistanceMode !=3D VL53LX_DISTANCEMODE_LONG)) + return VL53LX_ERROR_INVALID_PARAMS; + + if (IsL4(Dev) && (DistanceMode =3D=3D VL53LX_DISTANCEMODE_SHORT)) + return VL53LX_ERROR_INVALID_PARAMS; + + inter_measurement_period_ms =3D VL53LXDevDataGet(Dev, LLData.inter_measur= ement_period_ms); + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_get_timeouts_us(Dev, &PhaseCalTimeoutUs, &MmTimeoutUs,= &TimingBudget); + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D SetPresetModeL3CX(Dev, DistanceMode, inter_measurement_period= _ms); + + if (Status =3D=3D VL53LX_ERROR_NONE) { + VL53LXDevDataSet(Dev, CurrentParameters.DistanceMode, DistanceMode); + } + + if (Status =3D=3D VL53LX_ERROR_NONE) { + Status =3D VL53LX_set_timeouts_us(Dev, PhaseCalTimeoutUs, MmTimeoutUs, T= imingBudget); + + if (Status =3D=3D VL53LX_ERROR_NONE) + VL53LXDevDataSet(Dev, LLData.range_config_timeout_us, TimingBudget); + } + return Status; +} + +VL53LX_Error VL53LX_set_offset_correction_mode(VL53LX_DEV Dev, VL53LX_Offs= etCorrectionMode offset_cor_mode) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->offset_correction_mode =3D offset_cor_mode; + + return status; +} + +VL53LX_Error VL53LX_SetOffsetCorrectionMode(VL53LX_DEV Dev, VL53LX_OffsetC= orrectionModes OffsetCorrectionMode) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_OffsetCorrectionMode offset_cor_mode; + + if (OffsetCorrectionMode =3D=3D VL53LX_OFFSETCORRECTIONMODE_PERVCSEL) + offset_cor_mode =3D VL53LX_OFFSETCORRECTIONMODE__PER_VCSEL_OFFSETS; + else { + offset_cor_mode =3D VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS; + if (OffsetCorrectionMode !=3D VL53LX_OFFSETCORRECTIONMODE_STANDARD) + Status =3D VL53LX_ERROR_INVALID_PARAMS; + } + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_set_offset_correction_mode(Dev, offset_cor_mode); + + return Status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_disable(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_enabled =3D 0; + return status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_apply_disable(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_apply_enabled =3D 0; + + return status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_single_apply_disable(VL53LX_D= EV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_single_apply =3D 0; + + return status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_enable(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_enabled =3D 1; + + return status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_apply_enable(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_apply_enabled =3D 1; + + return status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_single_apply_enable(VL53LX_DE= V Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_single_apply =3D 1; + + return status; +} + +VL53LX_Error VL53LX_SmudgeCorrectionEnable(VL53LX_DEV Dev, VL53LX_SmudgeCo= rrectionModes Mode) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_Error s1 =3D VL53LX_ERROR_NONE; + VL53LX_Error s2 =3D VL53LX_ERROR_NONE; + VL53LX_Error s3 =3D VL53LX_ERROR_NONE; + + switch (Mode) { + case VL53LX_SMUDGE_CORRECTION_NONE: + s1 =3D VL53LX_dynamic_xtalk_correction_disable(Dev); + s2 =3D VL53LX_dynamic_xtalk_correction_apply_disable(Dev); + s3 =3D VL53LX_dynamic_xtalk_correction_single_apply_disable(Dev); + break; + case VL53LX_SMUDGE_CORRECTION_CONTINUOUS: + s1 =3D VL53LX_dynamic_xtalk_correction_enable(Dev); + s2 =3D VL53LX_dynamic_xtalk_correction_apply_enable(Dev); + s3 =3D VL53LX_dynamic_xtalk_correction_single_apply_disable(Dev); + break; + case VL53LX_SMUDGE_CORRECTION_SINGLE: + s1 =3D VL53LX_dynamic_xtalk_correction_enable(Dev); + s2 =3D VL53LX_dynamic_xtalk_correction_apply_enable(Dev); + s3 =3D VL53LX_dynamic_xtalk_correction_single_apply_enable(Dev); + break; + case VL53LX_SMUDGE_CORRECTION_DEBUG: + s1 =3D VL53LX_dynamic_xtalk_correction_enable(Dev); + s2 =3D VL53LX_dynamic_xtalk_correction_apply_disable(Dev); + s3 =3D VL53LX_dynamic_xtalk_correction_single_apply_disable(Dev); + break; + default: + Status =3D VL53LX_ERROR_INVALID_PARAMS; + break; + } + + if (Status =3D=3D VL53LX_ERROR_NONE) { + Status =3D s1; + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D s2; + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D s3; + } + return Status; +} + +static VL53LX_Error CheckValidRectRoi(VL53LX_UserRoi_t ROI) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + if ((ROI.TopLeftX > 15) || (ROI.TopLeftY > 15) || (ROI.BotRightX > 15) ||= (ROI.BotRightY > 15)) + Status =3D VL53LX_ERROR_INVALID_PARAMS; + if ((ROI.TopLeftX > ROI.BotRightX) || (ROI.TopLeftY < ROI.BotRightY)) + Status =3D VL53LX_ERROR_INVALID_PARAMS; + + return Status; +} + +VL53LX_Error VL53LX_init_zone_config_histogram_bins(VL53LX_zone_config_t *= pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t i; + + for (i =3D 0; i < pdata->max_zones; i++) + pdata->bin_config[i] =3D VL53LX_ZONECONFIG_BINCONFIG__LOWAMB; + + return status; +} + + +VL53LX_Error VL53LX_set_zone_config(VL53LX_DEV Dev, VL53LX_zone_config_t *= pzone_cfg) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + memcpy(&(pdev->zone_cfg.user_zones), &(pzone_cfg->user_zones), sizeof(pde= v->zone_cfg.user_zones)); + + pdev->zone_cfg.max_zones =3D pzone_cfg->max_zones; + pdev->zone_cfg.active_zones =3D pzone_cfg->active_zones; + + status =3D VL53LX_init_zone_config_histogram_bins(&pdev->zone_cfg); + + if (pzone_cfg->active_zones =3D=3D 0) + pdev->gen_cfg.global_config__stream_divider =3D 0; + else if (pzone_cfg->active_zones < VL53LX_MAX_USER_ZONES) + pdev->gen_cfg.global_config__stream_divider =3D pzone_cfg->active_zones = + 1; + else + pdev->gen_cfg.global_config__stream_divider =3D VL53LX_MAX_USER_ZONES + = 1; + + return status; +} + +VL53LX_Error VL53LX_SetUserROI(VL53LX_DEV Dev, VL53LX_UserRoi_t *pRoi) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_zone_config_t zone_cfg; + uint8_t x_centre, y_centre, width, height; + + Status =3D CheckValidRectRoi(*pRoi); + if (Status !=3D VL53LX_ERROR_NONE) + return VL53LX_ERROR_INVALID_PARAMS; + + x_centre =3D (pRoi->BotRightX + pRoi->TopLeftX + 1) / 2; + y_centre =3D (pRoi->TopLeftY + pRoi->BotRightY + 1) / 2; + width =3D (pRoi->BotRightX - pRoi->TopLeftX); + height =3D (pRoi->TopLeftY - pRoi->BotRightY); + zone_cfg.max_zones =3D 1; + zone_cfg.active_zones =3D 0; + zone_cfg.user_zones[0].x_centre =3D x_centre; + zone_cfg.user_zones[0].y_centre =3D y_centre; + zone_cfg.user_zones[0].width =3D width; + zone_cfg.user_zones[0].height =3D height; + if ((width < 3) || (height < 3)) + Status =3D VL53LX_ERROR_INVALID_PARAMS; + else + Status =3D VL53LX_set_zone_config(Dev, &zone_cfg); + + return Status; +} + +static int stmvl53lx_sendparams(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + rc =3D VL53LX_SetXTalkCompensationEnable(&data->stdev, data->crosstalk_en= able); + if (rc) { + vl53lx_errmsg("VL53LX_SetXTalkCompensationEnable %d fail %d", data->cros= stalk_enable, rc); + rc =3D store_last_error(data, rc); + goto done; + } + vl53lx_dbgmsg("Xtalk enable @%d\n", data->crosstalk_enable); + + rc =3D VL53LX_SetDistanceMode(&data->stdev, data->distance_mode); + if (rc) { + vl53lx_errmsg("VL53LX_SetDistanceMode %d fail %d", data->distance_mode, = rc); + rc =3D store_last_error(data, rc); + goto done; + } + vl53lx_dbgmsg("distance mode @%d\n", data->distance_mode); + + rc =3D VL53LX_SetMeasurementTimingBudgetMicroSeconds(&data->stdev, data->= timing_budget); + if (rc) { + vl53lx_errmsg("SetTimingBudget %d fail %d", data->timing_budget, rc); + rc =3D store_last_error(data, rc); + goto done; + } + vl53lx_dbgmsg("timing budget @%d\n", data->timing_budget); + + rc =3D VL53LX_SetOffsetCorrectionMode(&data->stdev, data->offset_correcti= on_mode); + if (rc) { + vl53lx_errmsg("offset correction mode %d fail %d", data->offset_correcti= on_mode, rc); + rc =3D store_last_error(data, rc); + goto done; + } + vl53lx_dbgmsg("offset correction mode @%d\n", data->offset_correction_mod= e); + + rc =3D VL53LX_SmudgeCorrectionEnable(&data->stdev, data->smudge_correcti= on_mode); + if (rc) { + vl53lx_errmsg("smudge correction mode %d fail %d", data->smudge_correcti= on_mode, rc); + rc =3D store_last_error(data, rc); + goto done; + } + vl53lx_dbgmsg("smudge correction mode @%d\n", data->smudge_correction_mod= e); + + rc =3D VL53LX_SetUserROI(&data->stdev, &data->roi_cfg); + if (rc) { + vl53lx_errmsg("VL53LX_SetUserROI fail %d\n", rc); + rc =3D store_last_error(data, rc); + goto done; + } + vl53lx_dbgmsg("ROI set TopLeft(%d %d) BottomRight(%d %d)\n", data->roi_cf= g.TopLeftX, data->roi_cfg.TopLeftY, data->roi_cfg.BotRightX, data->roi_cfg.= BotRightY); + +done: + return rc; +} + +static void kill_mz_data(VL53LX_MultiRangingData_t *pdata) +{ + int i; + + memset(pdata, 0, sizeof(*pdata)); + for (i =3D 0; i < VL53LX_MAX_RANGE_RESULTS; i++) + pdata->RangeData[i].RangeStatus =3D VL53LX_RANGESTATUS_NONE; +} + +VL53LX_Error VL53LX_enable_powerforce(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + status =3D VL53LX_set_powerforce_register(Dev, 0x01); + + return status; +} + +VL53LX_Error VL53LX_get_tuning_parm(VL53LX_DEV Dev, VL53LX_TuningParms tun= ing_parm_key, int32_t *ptuning_parm_value) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_hist_post_process_config_t *pHP =3D &(pdev->histpostprocess); + VL53LX_xtalkextract_config_t *pXC =3D &(pdev->xtalk_extract_cfg); + + switch (tuning_parm_key) { + case VL53LX_TUNINGPARM_VERSION: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_tuning_parm_versi= on; + break; + case VL53LX_TUNINGPARM_KEY_TABLE_VERSION: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_tuning_parm_key_t= able_version; + break; + case VL53LX_TUNINGPARM_LLD_VERSION: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_tuning_parm_lld_v= ersion; + break; + case VL53LX_TUNINGPARM_HIST_ALGO_SELECT: + *ptuning_parm_value =3D (int32_t)pHP->hist_algo_select; + break; + case VL53LX_TUNINGPARM_HIST_TARGET_ORDER: + *ptuning_parm_value =3D (int32_t)pHP->hist_target_order; + break; + case VL53LX_TUNINGPARM_HIST_FILTER_WOI_0: + *ptuning_parm_value =3D (int32_t)pHP->filter_woi0; + break; + case VL53LX_TUNINGPARM_HIST_FILTER_WOI_1: + *ptuning_parm_value =3D (int32_t)pHP->filter_woi1; + break; + case VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD: + *ptuning_parm_value =3D (int32_t)pHP->hist_amb_est_method; + break; + case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0: + *ptuning_parm_value =3D (int32_t)pHP->ambient_thresh_sigma0; + break; + case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1: + *ptuning_parm_value =3D (int32_t)pHP->ambient_thresh_sigma1; + break; + case VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS: + *ptuning_parm_value =3D (int32_t)pHP->min_ambient_thresh_events; + break; + case VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER: + *ptuning_parm_value =3D (int32_t)pHP->ambient_thresh_events_scaler; + break; + case VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD: + *ptuning_parm_value =3D (int32_t)pHP->noise_threshold; + break; + case VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT: + *ptuning_parm_value =3D (int32_t)pHP->signal_total_events_limit; + break; + case VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM: + *ptuning_parm_value =3D (int32_t)pHP->sigma_estimator__sigma_ref_mm; + break; + case VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM: + *ptuning_parm_value =3D (int32_t)pHP->sigma_thresh; + break; + case VL53LX_TUNINGPARM_HIST_GAIN_FACTOR: + *ptuning_parm_value =3D (int32_t)pdev->gain_cal.histogram_ranging_gain_f= actor; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE: + *ptuning_parm_value =3D (int32_t)pHP->algo__consistency_check__phase_tol= erance; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM: + *ptuning_parm_value =3D (int32_t)pHP->algo__consistency_check__min_max_t= olerance; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA: + *ptuning_parm_value =3D (int32_t)pHP->algo__consistency_check__event_sig= ma; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT: + *ptuning_parm_value =3D (int32_t)pHP->algo__consistency_check__event_min= _spad_count; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hi= st_long; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hi= st_med; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hi= st_short; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_ref_hi= st_long; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_ref_hi= st_med; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_ref_hi= st_short; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM: + *ptuning_parm_value =3D (int32_t)(pdev->xtalk_cfg.algo__crosstalk_detect= _min_valid_range_mm); + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM: + *ptuning_parm_value =3D (int32_t)(pdev->xtalk_cfg.algo__crosstalk_detect= _max_valid_range_mm); + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM: + *ptuning_parm_value =3D (int32_t)pdev->xtalk_cfg.algo__crosstalk_detect_= max_sigma_mm; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE: + *ptuning_parm_value =3D (int32_t)pHP->algo__crosstalk_detect_min_max_tol= erance; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS: + *ptuning_parm_value =3D (int32_t)(pdev->xtalk_cfg.algo__crosstalk_detect= _max_valid_rate_kcps); + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA: + *ptuning_parm_value =3D (int32_t)pHP->algo__crosstalk_detect_event_sigma; + break; + case VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS: + *ptuning_parm_value =3D (int32_t)pdev->xtalk_cfg.histogram_mode_crosstal= k_margin_kcps; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_consistency_lite_= phase_tolerance; + break; + case VL53LX_TUNINGPARM_PHASECAL_TARGET: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_phasecal_target; + break; + case VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_cal_repeat_rate; + break; + case VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR: + *ptuning_parm_value =3D (int32_t)pdev->gain_cal.standard_ranging_gain_fa= ctor; + break; + case VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_min_clip; + break; + case VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_long_sigma_t= hresh_mm; + break; + case VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_med_sigma_th= resh_mm; + break; + case VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_short_sigma_= thresh_mm; + break; + case VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS: + *ptuning_parm_value =3D (int32_t)(pdev->tuning_parms.tp_lite_long_min_co= unt_rate_rtn_mcps); + break; + case VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_med_min_coun= t_rate_rtn_mcps; + break; + case VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS: + *ptuning_parm_value =3D (int32_t)(pdev->tuning_parms.tp_lite_short_min_c= ount_rate_rtn_mcps); + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_sigma_est_pu= lse_width_ns; + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_sigma_est_am= b_width_ns; + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_sigma_ref_mm; + break; + case VL53LX_TUNINGPARM_LITE_RIT_MULT: + *ptuning_parm_value =3D (int32_t)pdev->xtalk_cfg.crosstalk_range_ignore_= threshold_mult; + break; + case VL53LX_TUNINGPARM_LITE_SEED_CONFIG: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_seed_cfg; + break; + case VL53LX_TUNINGPARM_LITE_QUANTIFIER: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_quantifier; + break; + case VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_lite_first_order_= select; + break; + case VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS: + *ptuning_parm_value =3D (int32_t)pdev->xtalk_cfg.lite_mode_crosstalk_mar= gin_kcps; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_rtn_li= te_long; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_rtn_li= te_med; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_rtn_li= te_short; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_ref_li= te_long; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_ref_li= te_med; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_init_phase_ref_li= te_short; + break; + case VL53LX_TUNINGPARM_TIMED_SEED_CONFIG: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_timed_seed_cfg; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA: + *ptuning_parm_value =3D (int32_t)pdev->dmax_cfg.signal_thresh_sigma; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0: + *ptuning_parm_value =3D (int32_t)pdev->dmax_cfg.target_reflectance_for_d= max_calc[0]; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1: + *ptuning_parm_value =3D (int32_t)pdev->dmax_cfg.target_reflectance_for_d= max_calc[1]; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2: + *ptuning_parm_value =3D (int32_t)pdev->dmax_cfg.target_reflectance_for_d= max_calc[2]; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3: + *ptuning_parm_value =3D (int32_t)pdev->dmax_cfg.target_reflectance_for_d= max_calc[3]; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4: + *ptuning_parm_value =3D (int32_t)pdev->dmax_cfg.target_reflectance_for_d= max_calc[4]; + break; + case VL53LX_TUNINGPARM_VHV_LOOPBOUND: + *ptuning_parm_value =3D (int32_t)pdev->stat_nvm.vhv_config__timeout_macr= op_loop_bound; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE: + *ptuning_parm_value =3D (int32_t)pdev->refspadchar.device_test_mode; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD: + *ptuning_parm_value =3D (int32_t)pdev->refspadchar.VL53LX_p_005; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->refspadchar.timeout_us; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->refspadchar.target_count_rate_mcp= s; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->refspadchar.min_count_rate_limit_= mcps; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->refspadchar.max_count_rate_limit_= mcps; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES: + *ptuning_parm_value =3D (int32_t)pXC->num_of_samples; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM: + *ptuning_parm_value =3D (int32_t)pXC->algo__crosstalk_extract_min_valid_= range_mm; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM: + *ptuning_parm_value =3D (int32_t)pXC->algo__crosstalk_extract_max_valid_= range_mm; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS: + *ptuning_parm_value =3D (int32_t)pXC->dss_config__target_total_rate_mcps; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pXC->phasecal_config_timeout_us; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS: + *ptuning_parm_value =3D (int32_t)pXC->algo__crosstalk_extract_max_valid_= rate_kcps; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM: + *ptuning_parm_value =3D (int32_t)pXC->algo__crosstalk_extract_max_sigma_= mm; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pXC->mm_config_timeout_us; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pXC->range_config_timeout_us; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->offsetcal_cfg.dss_config__target_= total_rate_mcps; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->offsetcal_cfg.phasecal_config_tim= eout_us; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->offsetcal_cfg.mm_config_timeout_u= s; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->offsetcal_cfg.range_config_timeou= t_us; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES: + *ptuning_parm_value =3D (int32_t)pdev->offsetcal_cfg.pre_num_of_samples; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES: + *ptuning_parm_value =3D (int32_t)pdev->offsetcal_cfg.mm1_num_of_samples; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES: + *ptuning_parm_value =3D (int32_t)pdev->offsetcal_cfg.mm2_num_of_samples; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->zonecal_cfg.dss_config__target_to= tal_rate_mcps; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->zonecal_cfg.phasecal_config_timeo= ut_us; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->zonecal_cfg.mm_config_timeout_us; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES: + *ptuning_parm_value =3D (int32_t)pdev->zonecal_cfg.phasecal_num_of_sampl= es; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->zonecal_cfg.range_config_timeout_= us; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES: + *ptuning_parm_value =3D (int32_t)pdev->zonecal_cfg.zone_num_of_samples; + break; + case VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD: + *ptuning_parm_value =3D (int32_t)pdev->ssc_cfg.VL53LX_p_005; + break; + case VL53LX_TUNINGPARM_SPADMAP_VCSEL_START: + *ptuning_parm_value =3D (int32_t)pdev->ssc_cfg.vcsel_start; + break; + case VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->ssc_cfg.rate_limit_mcps; + break; + case VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_dss_target_lite_m= cps; + break; + case VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_dss_target_histo_= mcps; + break; + case VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_dss_target_histo_= mz_mcps; + break; + case VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_dss_target_timed_= mcps; + break; + case VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_phasecal_timeout_= lite_us; + break; + case VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_phasecal_timeout_= hist_long_us; + break; + case VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_phasecal_timeout_= hist_med_us; + break; + case VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_phasecal_timeout_= hist_short_us; + break; + case VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_phasecal_timeout_= mz_long_us; + break; + case VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_phasecal_timeout_= mz_med_us; + break; + case VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_phasecal_timeout_= mz_short_us; + break; + case VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_phasecal_timeout_= timed_us; + break; + case VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_mm_timeout_lite_u= s; + break; + case VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_mm_timeout_histo_= us; + break; + case VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_mm_timeout_mz_us; + break; + case VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_mm_timeout_timed_= us; + break; + case VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_range_timeout_lit= e_us; + break; + case VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_range_timeout_his= to_us; + break; + case VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_range_timeout_mz_= us; + break; + case VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_range_timeout_tim= ed_us; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.smudge_marg= in; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.noise_margi= n; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.user_xtalk_= offset_limit; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.user_xtalk_= offset_limit_hi; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.sample_limi= t; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.single_xtal= k_delta; + break; + case VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.averaged_xt= alk_delta; + break; + case VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.smudge_corr= _clip_limit; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SCALER_CALC_METHOD: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.scaler_calc= _method; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.x_gradient_= scaler; + break; + case VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.y_gradient_= scaler; + break; + case VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.user_scaler= _set; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.smudge_corr= _single_apply; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD: + *ptuning_parm_value =3D (int32_t)(pdev->smudge_correct_config.smudge_cor= r_ambient_threshold); + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.nodetect_am= bient_threshold; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.nodetect_sa= mple_limit; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.nodetect_xt= alk_offset; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM: + *ptuning_parm_value =3D (int32_t)pdev->smudge_correct_config.nodetect_mi= n_range_mm; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND: + *ptuning_parm_value =3D (int32_t)pdev->low_power_auto_data.vhv_loop_boun= d; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_mm_timeout_lpa_us; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_range_timeout_lpa= _us; + break; + case VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS: + *ptuning_parm_value =3D (int32_t)pdev->tuning_parms.tp_dss_target_very_s= hort_mcps; + break; + case VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER: + *ptuning_parm_value =3D (int32_t) pdev->tuning_parms.tp_phasecal_patch_p= ower; + break; + case VL53LX_TUNINGPARM_HIST_MERGE: + *ptuning_parm_value =3D (int32_t) pdev->tuning_parms.tp_hist_merge; + break; + case VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD: + *ptuning_parm_value =3D (int32_t) pdev->tuning_parms.tp_reset_merge_thre= shold; + break; + case VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE: + *ptuning_parm_value =3D (int32_t) pdev->tuning_parms.tp_hist_merge_max_s= ize; + break; + case VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR: + *ptuning_parm_value =3D pdev->smudge_correct_config.max_smudge_factor; + break; + case VL53LX_TUNINGPARM_UWR_ENABLE: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_enable; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MIN: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_z_1_min; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MAX: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_z_1_max; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MIN: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_z_2_min; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MAX: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_z_2_max; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MIN: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_z_3_min; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MAX: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_z_3_max; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MIN: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_z_4_min; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MAX: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_z_4_max; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MIN: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_z_5_min; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MAX: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_z_5_max; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEA: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_corr_z_1_rangea; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEB: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_corr_z_1_rangeb; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEA: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_corr_z_2_rangea; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEB: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_corr_z_2_rangeb; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEA: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_corr_z_3_rangea; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEB: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_corr_z_3_rangeb; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEA: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_corr_z_4_rangea; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEB: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_corr_z_4_rangeb; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEA: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_corr_z_5_rangea; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEB: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_med_corr_z_5_rangeb; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MIN: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_z_1_min; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MAX: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_z_1_max; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MIN: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_z_2_min; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MAX: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_z_2_max; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MIN: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_z_3_min; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MAX: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_z_3_max; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MIN: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_z_4_min; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MAX: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_z_4_max; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MIN: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_z_5_min; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MAX: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_z_5_max; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEA: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_corr_z_1_rangea; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEB: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_corr_z_1_rangeb; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEA: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_corr_z_2_rangea; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEB: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_corr_z_2_rangeb; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEA: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_corr_z_3_rangea; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEB: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_corr_z_3_rangeb; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEA: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_corr_z_4_rangea; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEB: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_corr_z_4_rangeb; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEA: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_corr_z_5_rangea; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEB: + *ptuning_parm_value =3D pdev->tuning_parms.tp_uwr_lng_corr_z_5_rangeb; + break; + default: + *ptuning_parm_value =3D 0x7FFFFFFF; + status =3D VL53LX_ERROR_INVALID_PARAMS; + break; + + } + return status; +} + +VL53LX_Error VL53LX_load_patch(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + int32_t patch_tuning =3D 0; + uint8_t comms_buffer[256]; + uint32_t patch_power; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x00); + + if (status =3D=3D VL53LX_ERROR_NONE) + VL53LX_enable_powerforce(Dev); + + VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER, &patc= h_tuning); + + switch (patch_tuning) { + case 0: + patch_power =3D 0x00; + break; + case 1: + patch_power =3D 0x10; + break; + case 2: + patch_power =3D 0x20; + break; + case 3: + patch_power =3D 0x40; + break; + default: + patch_power =3D 0x00; + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + comms_buffer[0] =3D 0x29; + comms_buffer[1] =3D 0xC9; + comms_buffer[2] =3D 0x0E; + comms_buffer[3] =3D 0x40; + comms_buffer[4] =3D 0x28; + comms_buffer[5] =3D patch_power; + status =3D VL53LX_WriteMulti(Dev, VL53LX_PATCH__OFFSET_0, comms_buffer, = 6); + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + comms_buffer[0] =3D 0x03; + comms_buffer[1] =3D 0x6D; + comms_buffer[2] =3D 0x03; + comms_buffer[3] =3D 0x6F; + comms_buffer[4] =3D 0x07; + comms_buffer[5] =3D 0x29; + status =3D VL53LX_WriteMulti(Dev, VL53LX_PATCH__ADDRESS_0, comms_buffer,= 6); + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + comms_buffer[0] =3D 0x00; + comms_buffer[1] =3D 0x07; + status =3D VL53LX_WriteMulti(Dev, VL53LX_PATCH__JMP_ENABLES, comms_buffe= r, 2); + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + comms_buffer[0] =3D 0x00; + comms_buffer[1] =3D 0x07; + status =3D VL53LX_WriteMulti(Dev, VL53LX_PATCH__DATA_ENABLES, comms_buff= er, 2); + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_PATCH__CTRL, 0x01); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x01); + + return status; +} + +void VL53LX_encode_row_col(uint8_t row, uint8_t col, uint8_t *pspad_number) +{ + if (row > 7) + *pspad_number =3D 128 + (col << 3) + (15-row); + else + *pspad_number =3D ((15-col) << 3) + row; +} + +void VL53LX_encode_zone_size(uint8_t width, uint8_t height, uint8_t *penco= ded_xy_size) +{ + *pencoded_xy_size =3D (height << 4) + width; +} + +VL53LX_Error VL53LX_set_user_zone(VL53LX_DEV Dev, VL53LX_user_zone_t *puse= r_zone) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_encode_row_col(puser_zone->y_centre, puser_zone->x_centre, &(pdev-= >dyn_cfg.roi_config__user_roi_centre_spad)); + + VL53LX_encode_zone_size(puser_zone->width, puser_zone->height, &(pdev->dy= n_cfg.roi_config__user_roi_requested_global_xy_size)); + + return status; +} + +VL53LX_Error VL53LX_set_zone_dss_config(VL53LX_DEV Dev, VL53LX_zone_privat= e_dyn_cfg_t *pzone_dyn_cfg) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_ll_driver_state_t *pstate =3D &(pdev->ll_state); + + if (pstate->cfg_device_state =3D=3D VL53LX_DEVICESTATE_RANGING_DSS_MANUAL= ) { + pdev->gen_cfg.dss_config__roi_mode_control =3D VL53LX_DSS_CONTROL__MODE_= EFFSPADS; + pdev->gen_cfg.dss_config__manual_effective_spads_select =3D pzone_dyn_cf= g->dss_requested_effective_spad_count; + } else { + pdev->gen_cfg.dss_config__roi_mode_control =3D VL53LX_DSS_CONTROL__MODE_= TARGET_RATE; + } + + return status; +} + +VL53LX_Error VL53LX_save_cfg_data(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev); + + VL53LX_zone_private_dyn_cfg_t *pzone_dyn_cfg; + VL53LX_dynamic_config_t *pdynamic =3D &(pdev->dyn_cfg); + + pzone_dyn_cfg =3D &(pres->zone_dyn_cfgs.VL53LX_p_003[pdev->ll_state.cfg_z= one_id]); + pzone_dyn_cfg->expected_stream_count =3D pdev->ll_state.cfg_stream_count; + pzone_dyn_cfg->expected_gph_id =3D pdev->ll_state.cfg_gph_id; + pzone_dyn_cfg->roi_config__user_roi_centre_spad =3D pdynamic->roi_config_= _user_roi_centre_spad; + pzone_dyn_cfg->roi_config__user_roi_requested_global_xy_size =3D pdynamic= ->roi_config__user_roi_requested_global_xy_size; + + return status; +} + +VL53LX_Error VL53LX_i2c_encode_static_nvm_managed(VL53LX_static_nvm_manage= d_t *pdata, uint16_t buf_size, uint8_t *pbuffer) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + *(pbuffer + 0) =3D pdata->i2c_slave__device_address & 0x7F; + *(pbuffer + 1) =3D pdata->ana_config__vhv_ref_sel_vddpix & 0xF; + *(pbuffer + 2) =3D pdata->ana_config__vhv_ref_sel_vquench & 0x7F; + *(pbuffer + 3) =3D pdata->ana_config__reg_avdd1v2_sel & 0x3; + *(pbuffer + 4) =3D pdata->ana_config__fast_osc__trim & 0x7F; + VL53LX_i2c_encode_uint16_t(pdata->osc_measured__fast_osc__frequency, 2, p= buffer + 5); + *(pbuffer + 7) =3D pdata->vhv_config__timeout_macrop_loop_bound; + *(pbuffer + 8) =3D pdata->vhv_config__count_thresh; + *(pbuffer + 9) =3D pdata->vhv_config__offset & 0x3F; + *(pbuffer + 10) =3D pdata->vhv_config__init; + + return status; +} + +VL53LX_Error VL53LX_i2c_decode_static_nvm_managed(uint16_t buf_size, uint8= _t *pbuffer, VL53LX_static_nvm_managed_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + pdata->i2c_slave__device_address =3D + (*(pbuffer + 0)) & 0x7F; + pdata->ana_config__vhv_ref_sel_vddpix =3D + (*(pbuffer + 1)) & 0xF; + pdata->ana_config__vhv_ref_sel_vquench =3D + (*(pbuffer + 2)) & 0x7F; + pdata->ana_config__reg_avdd1v2_sel =3D + (*(pbuffer + 3)) & 0x3; + pdata->ana_config__fast_osc__trim =3D + (*(pbuffer + 4)) & 0x7F; + pdata->osc_measured__fast_osc__frequency =3D + (VL53LX_i2c_decode_uint16_t(2, pbuffer + 5)); + pdata->vhv_config__timeout_macrop_loop_bound =3D + (*(pbuffer + 7)); + pdata->vhv_config__count_thresh =3D + (*(pbuffer + 8)); + pdata->vhv_config__offset =3D + (*(pbuffer + 9)) & 0x3F; + pdata->vhv_config__init =3D + (*(pbuffer + 10)); + + return status; +} + +VL53LX_Error VL53LX_i2c_encode_static_config(VL53LX_static_config_t *pdata= , uint16_t buf_size, uint8_t *pbuffer) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + VL53LX_i2c_encode_uint16_t(pdata->dss_config__target_total_rate_mcps, 2, = pbuffer + 0); + *(pbuffer + 2) =3D pdata->debug__ctrl & 0x1; + *(pbuffer + 3) =3D pdata->test_mode__ctrl & 0xF; + *(pbuffer + 4) =3D pdata->clk_gating__ctrl & 0xF; + *(pbuffer + 5) =3D pdata->nvm_bist__ctrl & 0x1F; + *(pbuffer + 6) =3D pdata->nvm_bist__num_nvm_words & 0x7F; + *(pbuffer + 7) =3D pdata->nvm_bist__start_address & 0x7F; + *(pbuffer + 8) =3D pdata->host_if__status & 0x1; + *(pbuffer + 9) =3D pdata->pad_i2c_hv__config; + *(pbuffer + 10) =3D pdata->pad_i2c_hv__extsup_config & 0x1; + *(pbuffer + 11) =3D pdata->gpio_hv_pad__ctrl & 0x3; + *(pbuffer + 12) =3D pdata->gpio_hv_mux__ctrl & 0x1F; + *(pbuffer + 13) =3D pdata->gpio__tio_hv_status & 0x3; + *(pbuffer + 14) =3D pdata->gpio__fio_hv_status & 0x3; + *(pbuffer + 15) =3D pdata->ana_config__spad_sel_pswidth & 0x7; + *(pbuffer + 16) =3D pdata->ana_config__vcsel_pulse_width_offset & 0x1F; + *(pbuffer + 17) =3D pdata->ana_config__fast_osc__config_ctrl & 0x1; + *(pbuffer + 18) =3D pdata->sigma_estimator__effective_pulse_width_ns; + *(pbuffer + 19) =3D pdata->sigma_estimator__effective_ambient_width_ns; + *(pbuffer + 20) =3D pdata->sigma_estimator__sigma_ref_mm; + *(pbuffer + 21) =3D pdata->algo__crosstalk_compensation_valid_height_mm; + *(pbuffer + 22) =3D pdata->spare_host_config__static_config_spare_0; + *(pbuffer + 23) =3D pdata->spare_host_config__static_config_spare_1; + VL53LX_i2c_encode_uint16_t(pdata->algo__range_ignore_threshold_mcps, 2, p= buffer + 24); + *(pbuffer + 26) =3D pdata->algo__range_ignore_valid_height_mm; + *(pbuffer + 27) =3D pdata->algo__range_min_clip; + *(pbuffer + 28) =3D pdata->algo__consistency_check__tolerance & 0xF; + *(pbuffer + 29) =3D pdata->spare_host_config__static_config_spare_2; + *(pbuffer + 30) =3D pdata->sd_config__reset_stages_msb & 0xF; + *(pbuffer + 31) =3D pdata->sd_config__reset_stages_lsb; + + return status; +} + +VL53LX_Error VL53LX_i2c_encode_general_config(VL53LX_general_config_t *pda= ta, uint16_t buf_size, uint8_t *pbuffer) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + *(pbuffer + 0) =3D pdata->gph_config__stream_count_update_value; + *(pbuffer + 1) =3D pdata->global_config__stream_divider; + *(pbuffer + 2) =3D pdata->system__interrupt_config_gpio; + *(pbuffer + 3) =3D pdata->cal_config__vcsel_start & 0x7F; + VL53LX_i2c_encode_uint16_t(pdata->cal_config__repeat_rate & 0xFFF, 2, pbu= ffer + 4); + *(pbuffer + 6) =3D pdata->global_config__vcsel_width & 0x7F; + *(pbuffer + 7) =3D pdata->phasecal_config__timeout_macrop; + *(pbuffer + 8) =3D pdata->phasecal_config__target; + *(pbuffer + 9) =3D pdata->phasecal_config__override & 0x1; + *(pbuffer + 11) =3D pdata->dss_config__roi_mode_control & 0x7; + VL53LX_i2c_encode_uint16_t(pdata->system__thresh_rate_high, 2, pbuffer + = 12); + VL53LX_i2c_encode_uint16_t(pdata->system__thresh_rate_low, 2, pbuffer + 1= 4); + VL53LX_i2c_encode_uint16_t(pdata->dss_config__manual_effective_spads_sele= ct, 2, pbuffer + 16); + *(pbuffer + 18) =3D pdata->dss_config__manual_block_select; + *(pbuffer + 19) =3D pdata->dss_config__aperture_attenuation; + *(pbuffer + 20) =3D pdata->dss_config__max_spads_limit; + *(pbuffer + 21) =3D pdata->dss_config__min_spads_limit; + + return status; +} + +void VL53LX_i2c_encode_uint32_t(uint32_t ip_value, uint16_t count, uint8_t= *pbuffer) +{ + uint16_t i =3D 0; + uint32_t VL53LX_p_003 =3D 0; + + VL53LX_p_003 =3D ip_value; + + for (i =3D 0; i < count; i++) { + pbuffer[count-i-1] =3D (uint8_t)(VL53LX_p_003 & 0x00FF); + VL53LX_p_003 =3D VL53LX_p_003 >> 8; + } +} + +uint32_t VL53LX_i2c_decode_uint32_t(uint16_t count, uint8_t *pbuffer) +{ + uint32_t value =3D 0x00; + + while (count-- > 0) + value =3D (value << 8) | (uint32_t)*pbuffer++; + + return value; +} + +VL53LX_Error VL53LX_i2c_encode_timing_config(VL53LX_timing_config_t *pdata= , uint16_t buf_size, uint8_t *pbuffer) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + *(pbuffer + 0) =3D pdata->mm_config__timeout_macrop_a_hi & 0xF; + *(pbuffer + 1) =3D pdata->mm_config__timeout_macrop_a_lo; + *(pbuffer + 2) =3D pdata->mm_config__timeout_macrop_b_hi & 0xF; + *(pbuffer + 3) =3D pdata->mm_config__timeout_macrop_b_lo; + *(pbuffer + 4) =3D pdata->range_config__timeout_macrop_a_hi & 0xF; + *(pbuffer + 5) =3D pdata->range_config__timeout_macrop_a_lo; + *(pbuffer + 6) =3D pdata->range_config__vcsel_period_a & 0x3F; + *(pbuffer + 7) =3D pdata->range_config__timeout_macrop_b_hi & 0xF; + *(pbuffer + 8) =3D pdata->range_config__timeout_macrop_b_lo; + *(pbuffer + 9) =3D pdata->range_config__vcsel_period_b & 0x3F; + VL53LX_i2c_encode_uint16_t(pdata->range_config__sigma_thresh, 2, pbuffer = + 10); + VL53LX_i2c_encode_uint16_t(pdata->range_config__min_count_rate_rtn_limit_= mcps, 2, pbuffer + 12); + *(pbuffer + 14) =3D pdata->range_config__valid_phase_low; + *(pbuffer + 15) =3D pdata->range_config__valid_phase_high; + VL53LX_i2c_encode_uint32_t(pdata->system__intermeasurement_period, 4, pbu= ffer + 18); + *(pbuffer + 22) =3D pdata->system__fractional_enable & 0x1; + + return status; +} + +VL53LX_Error VL53LX_i2c_encode_dynamic_config(VL53LX_dynamic_config_t *pda= ta, uint16_t buf_size, uint8_t *pbuffer) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + *(pbuffer + 0) =3D pdata->system__grouped_parameter_hold_0 & 0x3; + VL53LX_i2c_encode_uint16_t(pdata->system__thresh_high, 2, pbuffer + 1); + VL53LX_i2c_encode_uint16_t(pdata->system__thresh_low, 2, pbuffer + 3); + *(pbuffer + 5) =3D pdata->system__enable_xtalk_per_quadrant & 0x1; + *(pbuffer + 6) =3D pdata->system__seed_config & 0x7; + *(pbuffer + 7) =3D pdata->sd_config__woi_sd0; + *(pbuffer + 8) =3D pdata->sd_config__woi_sd1; + *(pbuffer + 9) =3D pdata->sd_config__initial_phase_sd0 & 0x7F; + *(pbuffer + 10) =3D pdata->sd_config__initial_phase_sd1 & 0x7F; + *(pbuffer + 11) =3D pdata->system__grouped_parameter_hold_1 & 0x3; + *(pbuffer + 12) =3D pdata->sd_config__first_order_select & 0x3; + *(pbuffer + 13) =3D pdata->sd_config__quantifier & 0xF; + *(pbuffer + 14) =3D pdata->roi_config__user_roi_centre_spad; + *(pbuffer + 15) =3D pdata->roi_config__user_roi_requested_global_xy_size; + *(pbuffer + 16) =3D pdata->system__sequence_config; + *(pbuffer + 17) =3D pdata->system__grouped_parameter_hold & 0x3; + + return status; +} + +VL53LX_Error VL53LX_update_internal_stream_counters(VL53LX_DEV Dev, uint8_= t external_stream_count, uint8_t *pinternal_stream_count, uint8_t *pinterna= l_stream_count_val) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t stream_divider; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + stream_divider =3D pdev->gen_cfg.global_config__stream_divider; + + if (stream_divider =3D=3D 0) { + *pinternal_stream_count =3D external_stream_count; + } else if (*pinternal_stream_count_val =3D=3D (stream_divider-1)) { + if (*pinternal_stream_count =3D=3D 0xFF) + *pinternal_stream_count =3D 0x80; + else + *pinternal_stream_count =3D *pinternal_stream_count + 1; + *pinternal_stream_count_val =3D 0; + + } else { + *pinternal_stream_count_val =3D *pinternal_stream_count_val + 1; + } + return status; +} + +VL53LX_Error VL53LX_update_ll_driver_rd_state(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_ll_driver_state_t *pstate =3D &(pdev->ll_state); + + if ((pdev->sys_ctrl.system__mode_start & VL53LX_DEVICEMEASUREMENTMODE_MOD= E_MASK) =3D=3D 0x00) { + pstate->rd_device_state =3D VL53LX_DEVICESTATE_SW_STANDBY; + pstate->rd_stream_count =3D 0; + pstate->rd_internal_stream_count =3D 0; + pstate->rd_internal_stream_count_val =3D 0; + pstate->rd_gph_id =3D VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->rd_timing_status =3D 0; + pstate->rd_zone_id =3D 0; + + } else { + if (pstate->rd_stream_count =3D=3D 0xFF) + pstate->rd_stream_count =3D 0x80; + else + pstate->rd_stream_count++; + + status =3D VL53LX_update_internal_stream_counters(Dev, pstate->rd_stream= _count, &(pstate->rd_internal_stream_count), &(pstate->rd_internal_stream_c= ount_val)); + pstate->rd_gph_id ^=3D VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + switch (pstate->rd_device_state) { + case VL53LX_DEVICESTATE_SW_STANDBY: + if ((pdev->dyn_cfg.system__grouped_parameter_hold & VL53LX_GROUPEDPARAM= ETERHOLD_ID_MASK) > 0) { + pstate->rd_device_state =3D + VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC; + } else { + if (pstate->rd_zone_id >=3D pdev->zone_cfg.active_zones) + pstate->rd_device_state =3D VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA; + else + pstate->rd_device_state =3D VL53LX_DEVICESTATE_RANGING_GATHER_DATA; + } + pstate->rd_stream_count =3D 0; + pstate->rd_internal_stream_count =3D 0; + pstate->rd_internal_stream_count_val =3D 0; + pstate->rd_timing_status =3D 0; + pstate->rd_zone_id =3D 0; + break; + case VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC: + pstate->rd_stream_count =3D 0; + pstate->rd_internal_stream_count =3D 0; + pstate->rd_internal_stream_count_val =3D 0; + pstate->rd_zone_id =3D 0; + if (pstate->rd_zone_id >=3D pdev->zone_cfg.active_zones) + pstate->rd_device_state =3D VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA; + else + pstate->rd_device_state =3D VL53LX_DEVICESTATE_RANGING_GATHER_DATA; + break; + case VL53LX_DEVICESTATE_RANGING_GATHER_DATA: + pstate->rd_zone_id++; + if (pstate->rd_zone_id >=3D pdev->zone_cfg.active_zones) + pstate->rd_device_state =3D VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA; + else + pstate->rd_device_state =3D VL53LX_DEVICESTATE_RANGING_GATHER_DATA; + break; + case VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA: + pstate->rd_zone_id =3D 0; + pstate->rd_timing_status ^=3D 0x01; + if (pstate->rd_zone_id >=3D pdev->zone_cfg.active_zones) + pstate->rd_device_state =3D VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA; + else + pstate->rd_device_state =3D VL53LX_DEVICESTATE_RANGING_GATHER_DATA; + break; + default: + pstate->rd_device_state =3D VL53LX_DEVICESTATE_SW_STANDBY; + pstate->rd_stream_count =3D 0; + pstate->rd_internal_stream_count =3D 0; + pstate->rd_internal_stream_count_val =3D 0; + pstate->rd_gph_id =3D VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->rd_timing_status =3D 0; + pstate->rd_zone_id =3D 0; + break; + } + } + return status; +} + +VL53LX_Error VL53LX_update_ll_driver_cfg_state(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev= ); + + VL53LX_ll_driver_state_t *pstate =3D &(pdev->ll_state); + VL53LX_zone_private_dyn_cfgs_t *pZ =3D &(pres->zone_dyn_cfgs); + + uint8_t prev_cfg_zone_id; + uint8_t prev_cfg_gph_id; + uint8_t prev_cfg_stream_count; + + if ((pdev->sys_ctrl.system__mode_start & VL53LX_DEVICEMEASUREMENTMODE_MOD= E_MASK) =3D=3D 0x00) { + pstate->cfg_device_state =3D VL53LX_DEVICESTATE_SW_STANDBY; + pstate->cfg_stream_count =3D 0; + pstate->cfg_internal_stream_count =3D 0; + pstate->cfg_internal_stream_count_val =3D 0; + pstate->cfg_gph_id =3D VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->cfg_timing_status =3D 0; + pstate->cfg_zone_id =3D 0; + prev_cfg_zone_id =3D 0; + prev_cfg_gph_id =3D 0; + prev_cfg_stream_count =3D 0; + + } else { + prev_cfg_gph_id =3D pstate->cfg_gph_id; + prev_cfg_zone_id =3D pstate->cfg_zone_id; + prev_cfg_stream_count =3D pstate->cfg_stream_count; + + if (pstate->cfg_stream_count =3D=3D 0xFF) + pstate->cfg_stream_count =3D 0x80; + else + pstate->cfg_stream_count++; + + status =3D VL53LX_update_internal_stream_counters(Dev, pstate->cfg_strea= m_count, &(pstate->cfg_internal_stream_count), &(pstate->cfg_internal_strea= m_count_val)); + + pstate->cfg_gph_id ^=3D VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + + switch (pstate->cfg_device_state) { + case VL53LX_DEVICESTATE_SW_STANDBY: + pstate->cfg_zone_id =3D 1; + if (pstate->cfg_zone_id > pdev->zone_cfg.active_zones) { + pstate->cfg_zone_id =3D 0; + pstate->cfg_timing_status ^=3D 0x01; + } + pstate->cfg_stream_count =3D 1; + + if (pdev->gen_cfg.global_config__stream_divider =3D=3D 0) { + pstate->cfg_internal_stream_count =3D 1; + pstate->cfg_internal_stream_count_val =3D 0; + } else { + pstate->cfg_internal_stream_count =3D 0; + pstate->cfg_internal_stream_count_val =3D 1; + } + pstate->cfg_device_state =3D VL53LX_DEVICESTATE_RANGING_DSS_AUTO; + break; + case VL53LX_DEVICESTATE_RANGING_DSS_AUTO: + pstate->cfg_zone_id++; + if (pstate->cfg_zone_id > pdev->zone_cfg.active_zones) { + pstate->cfg_zone_id =3D 0; + pstate->cfg_timing_status ^=3D 0x01; + + if (pdev->zone_cfg.active_zones > 0) { + pstate->cfg_device_state =3D + VL53LX_DEVICESTATE_RANGING_DSS_MANUAL; + } + } + break; + case VL53LX_DEVICESTATE_RANGING_DSS_MANUAL: + pstate->cfg_zone_id++; + if (pstate->cfg_zone_id > pdev->zone_cfg.active_zones) { + pstate->cfg_zone_id =3D 0; + pstate->cfg_timing_status ^=3D 0x01; + } + break; + default: + pstate->cfg_device_state =3D VL53LX_DEVICESTATE_SW_STANDBY; + pstate->cfg_stream_count =3D 0; + pstate->cfg_internal_stream_count =3D 0; + pstate->cfg_internal_stream_count_val =3D 0; + pstate->cfg_gph_id =3D VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + pstate->cfg_timing_status =3D 0; + pstate->cfg_zone_id =3D 0; + break; + } + } + if (pdev->zone_cfg.active_zones =3D=3D 0) { + pZ->VL53LX_p_003[prev_cfg_zone_id].expected_stream_count =3D prev_cfg_st= ream_count - 1; + pZ->VL53LX_p_003[pstate->rd_zone_id].expected_gph_id =3D prev_cfg_gph_id= ^ VL53LX_GROUPEDPARAMETERHOLD_ID_MASK; + } else { + pZ->VL53LX_p_003[prev_cfg_zone_id].expected_stream_count =3D prev_cfg_st= ream_count; + pZ->VL53LX_p_003[prev_cfg_zone_id].expected_gph_id =3D prev_cfg_gph_id; + } + return status; +} + +VL53LX_Error VL53LX_init_and_start_range(VL53LX_DEV Dev, uint8_t measureme= nt_mode, VL53LX_DeviceConfigLevel device_config_level) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev= ); + + uint8_t buffer[VL53LX_MAX_I2C_XFER_SIZE]; + + VL53LX_static_nvm_managed_t *pstatic_nvm =3D &(pdev->stat_nvm); + VL53LX_customer_nvm_managed_t *pcustomer_nvm =3D &(pdev->customer); + VL53LX_static_config_t *pstatic =3D &(pdev->stat_cfg); + VL53LX_general_config_t *pgeneral =3D &(pdev->gen_cfg); + VL53LX_timing_config_t *ptiming =3D &(pdev->tim_cfg); + VL53LX_dynamic_config_t *pdynamic =3D &(pdev->dyn_cfg); + VL53LX_system_control_t *psystem =3D &(pdev->sys_ctrl); + + VL53LX_ll_driver_state_t *pstate =3D &(pdev->ll_state); + VL53LX_customer_nvm_managed_t *pN =3D &(pdev->customer); + + uint8_t *pbuffer =3D &buffer[0]; + uint16_t i =3D 0; + uint16_t i2c_index =3D 0; + uint16_t i2c_buffer_offset_bytes =3D 0; + uint16_t i2c_buffer_size_bytes =3D 0; + + pdev->measurement_mode =3D measurement_mode; + + psystem->system__mode_start =3D (psystem->system__mode_start & VL53LX_DEV= ICEMEASUREMENTMODE_STOP_MASK) | measurement_mode; + + status =3D VL53LX_set_user_zone(Dev, &(pdev->zone_cfg.user_zones[pdev->ll= _state.cfg_zone_id])); + if (pdev->zone_cfg.active_zones > 0) { + status =3D VL53LX_set_zone_dss_config(Dev, &(pres->zone_dyn_cfgs.VL53LX_= p_003[pdev->ll_state.cfg_zone_id])); + } + + if (((pdev->sys_ctrl.system__mode_start & VL53LX_DEVICESCHEDULERMODE_HIST= OGRAM) =3D=3D 0x00) && (pdev->xtalk_cfg.global_crosstalk_compensation_enabl= e =3D=3D 0x01)) { + pdev->stat_cfg.algo__range_ignore_threshold_mcps =3D pdev->xtalk_cfg.cro= sstalk_range_ignore_threshold_rate_mcps; + } + + if (pdev->low_power_auto_data.low_power_auto_range_count =3D=3D 0xFF) + pdev->low_power_auto_data.low_power_auto_range_count =3D 0x0; + + if ((pdev->low_power_auto_data.is_low_power_auto_mode =3D=3D 1) && (pdev-= >low_power_auto_data.low_power_auto_range_count =3D=3D 0)) { + pdev->low_power_auto_data.saved_interrupt_config =3D pdev->gen_cfg.syste= m__interrupt_config_gpio; + pdev->gen_cfg.system__interrupt_config_gpio =3D 1 << 5; + if ((pdev->dyn_cfg.system__sequence_config & (VL53LX_SEQUENCE_MM1_EN | V= L53LX_SEQUENCE_MM2_EN)) =3D=3D 0x0) { + pN->algo__part_to_part_range_offset_mm =3D (pN->mm_config__outer_offset= _mm << 2); + } else { + pN->algo__part_to_part_range_offset_mm =3D 0x0; + } + if (device_config_level < VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS) { + device_config_level =3D VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS; + } + } + + if ((pdev->low_power_auto_data.is_low_power_auto_mode =3D=3D 1) && (pdev-= >low_power_auto_data.low_power_auto_range_count =3D=3D 1)) { + pdev->gen_cfg.system__interrupt_config_gpio =3D pdev->low_power_auto_dat= a.saved_interrupt_config; + device_config_level =3D VL53LX_DEVICECONFIGLEVEL_FULL; + } + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_save_cfg_data(Dev); + + switch (device_config_level) { + case VL53LX_DEVICECONFIGLEVEL_FULL: + i2c_index =3D VL53LX_STATIC_NVM_MANAGED_I2C_INDEX; + break; + case VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS: + i2c_index =3D VL53LX_CUSTOMER_NVM_MANAGED_I2C_INDEX; + break; + case VL53LX_DEVICECONFIGLEVEL_STATIC_ONWARDS: + i2c_index =3D VL53LX_STATIC_CONFIG_I2C_INDEX; + break; + case VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS: + i2c_index =3D VL53LX_GENERAL_CONFIG_I2C_INDEX; + break; + case VL53LX_DEVICECONFIGLEVEL_TIMING_ONWARDS: + i2c_index =3D VL53LX_TIMING_CONFIG_I2C_INDEX; + break; + case VL53LX_DEVICECONFIGLEVEL_DYNAMIC_ONWARDS: + i2c_index =3D VL53LX_DYNAMIC_CONFIG_I2C_INDEX; + break; + default: + i2c_index =3D VL53LX_SYSTEM_CONTROL_I2C_INDEX; + break; + } + i2c_buffer_size_bytes =3D (VL53LX_SYSTEM_CONTROL_I2C_INDEX + VL53LX_SYSTE= M_CONTROL_I2C_SIZE_BYTES) - i2c_index; + + pbuffer =3D &buffer[0]; + for (i =3D 0; i < i2c_buffer_size_bytes; i++) + *pbuffer++ =3D 0; + + if (device_config_level >=3D VL53LX_DEVICECONFIGLEVEL_FULL && status =3D= =3D VL53LX_ERROR_NONE) { + i2c_buffer_offset_bytes =3D VL53LX_STATIC_NVM_MANAGED_I2C_INDEX - i2c_in= dex; + status =3D VL53LX_i2c_encode_static_nvm_managed(pstatic_nvm, VL53LX_STAT= IC_NVM_MANAGED_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]); + } + if (device_config_level >=3D VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS &&= status =3D=3D VL53LX_ERROR_NONE) { + i2c_buffer_offset_bytes =3D VL53LX_CUSTOMER_NVM_MANAGED_I2C_INDEX - i2c_= index; + status =3D VL53LX_i2c_encode_customer_nvm_managed(pcustomer_nvm, VL53LX_= CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]); + } + if (device_config_level >=3D VL53LX_DEVICECONFIGLEVEL_STATIC_ONWARDS && s= tatus =3D=3D VL53LX_ERROR_NONE) { + i2c_buffer_offset_bytes =3D VL53LX_STATIC_CONFIG_I2C_INDEX - i2c_index; + status =3D VL53LX_i2c_encode_static_config(pstatic, VL53LX_STATIC_CONFIG= _I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]); + } + if (device_config_level >=3D VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS && = status =3D=3D VL53LX_ERROR_NONE) { + i2c_buffer_offset_bytes =3D VL53LX_GENERAL_CONFIG_I2C_INDEX - i2c_index; + status =3D VL53LX_i2c_encode_general_config(pgeneral, VL53LX_GENERAL_CON= FIG_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]); + } + if (device_config_level >=3D VL53LX_DEVICECONFIGLEVEL_TIMING_ONWARDS && s= tatus =3D=3D VL53LX_ERROR_NONE) { + i2c_buffer_offset_bytes =3D VL53LX_TIMING_CONFIG_I2C_INDEX - i2c_index; + status =3D VL53LX_i2c_encode_timing_config(ptiming, VL53LX_TIMING_CONFIG= _I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]); + } + if (device_config_level >=3D VL53LX_DEVICECONFIGLEVEL_DYNAMIC_ONWARDS && = status =3D=3D VL53LX_ERROR_NONE) { + i2c_buffer_offset_bytes =3D VL53LX_DYNAMIC_CONFIG_I2C_INDEX - i2c_index; + if ((psystem->system__mode_start & VL53LX_DEVICEMEASUREMENTMODE_BACKTOBA= CK) =3D=3D VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK) { + pdynamic->system__grouped_parameter_hold_0 =3D pstate->cfg_gph_id | 0x0= 1; + pdynamic->system__grouped_parameter_hold_1 =3D pstate->cfg_gph_id | 0x0= 1; + pdynamic->system__grouped_parameter_hold =3D pstate->cfg_gph_id; + } + status =3D VL53LX_i2c_encode_dynamic_config(pdynamic, VL53LX_DYNAMIC_CON= FIG_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]); + } + if (status =3D=3D VL53LX_ERROR_NONE) { + i2c_buffer_offset_bytes =3D VL53LX_SYSTEM_CONTROL_I2C_INDEX - i2c_index; + status =3D VL53LX_i2c_encode_system_control(psystem, VL53LX_SYSTEM_CONTR= OL_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]); + } + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_WriteMulti(Dev, i2c_index, buffer, (uint32_t)i2c_buffe= r_size_bytes); + } + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_update_ll_driver_rd_state(Dev); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_update_ll_driver_cfg_state(Dev); + + return status; +} + +VL53LX_Error VL53LX_StartMeasurement(VL53LX_DEV Dev) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + uint8_t DeviceMeasurementMode; + uint8_t i; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + VL53LX_load_patch(Dev); + for (i =3D 0; i < VL53LX_MAX_RANGE_RESULTS; i++) { + pdev->PreviousRangeMilliMeter[i] =3D 0; + pdev->PreviousRangeStatus[i] =3D 255; + pdev->PreviousExtendedRange[i] =3D 0; + } + pdev->PreviousStreamCount =3D 0; + pdev->PreviousRangeActiveResults =3D 0; + + DeviceMeasurementMode =3D VL53LXDevDataGet(Dev, LLData.measurement_mode); + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_init_and_start_range(Dev, DeviceMeasurementMode, VL53L= X_DEVICECONFIGLEVEL_FULL); + + return Status; +} + +VL53LX_Error VL53LX_WaitMeasurementDataReady(VL53LX_DEV Dev) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + Status =3D VL53LX_poll_for_range_completion(Dev, VL53LX_RANGE_COMPLETION_= POLLING_TIMEOUT_MS); + + return Status; +} + +VL53LX_Error VL53LX_is_new_data_ready(VL53LX_DEV Dev, uint8_t *pready) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t gpio__mux_active_high_hv =3D 0; + uint8_t gpio__tio_hv_status =3D 0; + uint8_t interrupt_ready =3D 0; + + gpio__mux_active_high_hv =3D pdev->stat_cfg.gpio_hv_mux__ctrl & VL53LX_DE= VICEINTERRUPTLEVEL_ACTIVE_MASK; + + if (gpio__mux_active_high_hv =3D=3D VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_HI= GH) + interrupt_ready =3D 0x01; + else + interrupt_ready =3D 0x00; + + status =3D VL53LX_RdByte(Dev, VL53LX_GPIO__TIO_HV_STATUS, &gpio__tio_hv_s= tatus); + + if ((gpio__tio_hv_status & 0x01) =3D=3D interrupt_ready) + *pready =3D 0x01; + else + *pready =3D 0x00; + + return status; +} + +VL53LX_Error VL53LX_GetMeasurementDataReady(VL53LX_DEV Dev, uint8_t *pMeas= urementDataReady) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + Status =3D VL53LX_is_new_data_ready(Dev, pMeasurementDataReady); + + return Status; +} + +long stmvl53lx_tv_dif(struct st_timeval *pstart_tv, struct st_timeval *pst= op_tv) +{ + long total_sec, total_usec; + + total_sec =3D pstop_tv->tv_sec - pstart_tv->tv_sec; + total_usec =3D (pstop_tv->tv_usec - pstart_tv->tv_usec); + + return total_sec*1000000+total_usec; +} + +VL53LX_Error VL53LX_GetMultiRangingData(VL53LX_DEV Dev, VL53LX_MultiRangin= gData_t *pMultiRangingData) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_range_results_t *presults =3D (VL53LX_range_results_t *) pdev->wAr= ea1; + + memset(pMultiRangingData, 0xFF, sizeof(VL53LX_MultiRangingData_t)); + + Status =3D VL53LX_get_device_results(Dev, VL53LX_DEVICERESULTSLEVEL_FULL,= presults); + Status =3D SetMeasurementData(Dev, presults, pMultiRangingData); + + return Status; +} + +VL53LX_Error VL53LX_get_histogram_debug_data(VL53LX_DEV Dev, VL53LX_histog= ram_bin_data_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + memcpy(pdata, &(pdev->hist_data), sizeof(VL53LX_histogram_bin_data_t)); + + return status; +} + +VL53LX_Error VL53LX_get_additional_data(VL53LX_DEV Dev, VL53LX_additional_= data_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdata->preset_mode =3D pdev->preset_mode; + pdata->zone_preset =3D pdev->zone_preset; + pdata->measurement_mode =3D pdev->measurement_mode; + pdata->offset_calibration_mode =3D pdev->offset_calibration_mode; + pdata->offset_correction_mode =3D pdev->offset_correction_mode; + pdata->dmax_mode =3D pdev->dmax_mode; + + pdata->phasecal_config_timeout_us =3D pdev->phasecal_config_timeout_us; + pdata->mm_config_timeout_us =3D pdev->mm_config_timeout_us; + pdata->range_config_timeout_us =3D pdev->range_config_timeout_us; + pdata->inter_measurement_period_ms =3D pdev->inter_measurement_period_ms; + pdata->dss_config__target_total_rate_mcps =3D pdev->dss_config__target_to= tal_rate_mcps; + + status =3D VL53LX_get_histogram_debug_data(Dev, &(pdata->VL53LX_p_006)); + + return status; +} + +VL53LX_Error VL53LX_GetAdditionalData(VL53LX_DEV Dev, VL53LX_AdditionalDat= a_t *pAdditionalData) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + Status =3D VL53LX_get_additional_data(Dev, pAdditionalData); + + return Status; +} + +static void detect_xtalk_value_change(struct stmvl53lx_data *data, VL53LX_= MultiRangingData_t *meas) +{ + data->is_xtalk_value_changed =3D meas->HasXtalkValueChanged ? true : data= ->is_xtalk_value_changed; +} + +static void stmvl53lx_input_push_data_multiobject(struct stmvl53lx_data *d= ata) +{ + VL53LX_MultiRangingData_t *mmeas =3D &data->meas.multi_range_data; + int i; + int rc =3D 0; + VL53LX_TargetRangeData_t *meas_array[4]; + VL53LX_CalibrationData_t calibration_data; + struct st_timeval tv; + struct input_dev *input =3D data->input_dev_ps; + + st_gettimeofday(&tv); + + for (i =3D 0; i < 4; i++) + meas_array[i] =3D &mmeas->RangeData[i]; + + rc =3D VL53LX_GetCalibrationData(&data->stdev, &calibration_data); + if (rc) { + vl53lx_errmsg("%d error:%d\n", __LINE__, rc); + return; + } + + input_report_abs(input, ABS_HAT0X, tv.tv_sec); + vl53lx_dbgmsg("ABS_HAT0X : %ld, %zu\n", tv.tv_sec, sizeof(tv.tv_sec)); + + input_report_abs(input, ABS_HAT0Y, tv.tv_usec); + vl53lx_dbgmsg("ABS_HAT0Y : %ld\n", tv.tv_usec); + + input_report_abs(input, ABS_WHEEL, meas_array[0]->AmbientRateRtnMegaCps); + vl53lx_dbgmsg("ABS_WHEEL : AmbRate =3D %d\n", meas_array[0]->AmbientRateR= tnMegaCps); + + input_report_abs(input, ABS_TILT_X, (mmeas->HasXtalkValueChanged << 16) |= (mmeas->StreamCount << 8) | ((mmeas->NumberOfObjectsFound & 0x3) << 6)); + vl53lx_dbgmsg("ABS_TILT_X :(%d):(%d):(%d)\n\n", mmeas->HasXtalkValueChang= ed, mmeas->StreamCount, mmeas->NumberOfObjectsFound); + + input_report_abs(input, ABS_TILT_Y, 0); + input_report_abs(input, ABS_TOOL_WIDTH, calibration_data.customer.algo__c= rosstalk_compensation_plane_offset_kcps); + + vl53lx_dbgmsg("ABS_TOOL_WIDTH Xtalk =3D %d\n", calibration_data.customer.= algo__crosstalk_compensation_plane_offset_kcps); + input_report_abs(input, ABS_BRAKE, mmeas->EffectiveSpadRtnCount << 16 | (= (meas_array[1]->RangeStatus) << 8) | meas_array[0]->RangeStatus); + vl53lx_dbgmsg("ABS_BRAKE : (%d):(%d):(%d)\n", mmeas->EffectiveSpadRtnCoun= t, meas_array[1]->RangeStatus, meas_array[0]->RangeStatus); + vl53lx_dbgmsg("ABS_BRAKE : 0x%X\n", (mmeas->EffectiveSpadRtnCount & 0xFFF= F) << 16 | ((meas_array[1]->RangeStatus) << 8) | meas_array[0]->RangeStatus= ); + + if (mmeas->NumberOfObjectsFound =3D=3D 0) { + input_sync(input); + return; + } + + input_report_abs(input, ABS_HAT1X, meas_array[0]->RangeMilliMeter << 16 |= (meas_array[0]->SigmaMilliMeter/65536)); + vl53lx_dbgmsg("ABS_HAT1X : 0x%X(%d:%d)\n", + meas_array[0]->RangeMilliMeter << 16 + | (meas_array[0]->SigmaMilliMeter/65536), + meas_array[0]->RangeMilliMeter, + (meas_array[0]->SigmaMilliMeter/65536)); + + input_report_abs(input, ABS_HAT1Y, meas_array[0]->RangeMinMilliMeter << 1= 6 | meas_array[0]->RangeMaxMilliMeter); + vl53lx_dbgmsg("ABS_HAT1Y : 0x%X(%d:%d)\n", + meas_array[0]->RangeMinMilliMeter << 16 + | meas_array[0]->RangeMaxMilliMeter, + meas_array[0]->RangeMinMilliMeter, + meas_array[0]->RangeMaxMilliMeter); + + if (mmeas->NumberOfObjectsFound > 1) { + input_report_abs(input, ABS_HAT2X, meas_array[1]->RangeMilliMeter << 16 = | (meas_array[1]->SigmaMilliMeter/65536)); + vl53lx_dbgmsg("ABS_HAT2X : 0x%x(%d:%d)\n", + meas_array[1]->RangeMilliMeter << 16 + | (meas_array[1]->SigmaMilliMeter/65536), + meas_array[1]->RangeMilliMeter, + (meas_array[1]->SigmaMilliMeter/65536)); + + input_report_abs(input, ABS_HAT2Y, meas_array[1]->RangeMinMilliMeter << = 16 | meas_array[1]->RangeMaxMilliMeter); + vl53lx_dbgmsg("ABS_HAT1Y : 0x%X(%d:%d)\n", + meas_array[1]->RangeMinMilliMeter << 16 + | meas_array[1]->RangeMaxMilliMeter, + meas_array[1]->RangeMinMilliMeter, + meas_array[1]->RangeMaxMilliMeter); + } + input_report_abs(input, ABS_HAT3X, meas_array[0]->SignalRateRtnMegaCps); + vl53lx_dbgmsg("ABS_HAT3X : SignalRateRtnMegaCps_0(%d)\n", meas_array[0]->= SignalRateRtnMegaCps); + if (mmeas->NumberOfObjectsFound > 1) { + input_report_abs(input, ABS_HAT3Y, meas_array[1]->SignalRateRtnMegaCps); + vl53lx_dbgmsg("ABS_HAT3Y : SignalRateRtnMegaCps_1(%d)\n", meas_array[1]-= >SignalRateRtnMegaCps); + } + input_report_abs(input, ABS_MISC, 0); + input_sync(input); +} + +static void stmvl53lx_input_push_data(struct stmvl53lx_data *data) +{ + stmvl53lx_input_push_data_multiobject(data); +} + +static void stmvl53lx_on_newdata_event(struct stmvl53lx_data *data) +{ + int rc =3D 0; + VL53LX_MultiRangingData_t *pmrange; + VL53LX_MultiRangingData_t *tmprange; + VL53LX_TargetRangeData_t RangeData[VL53LX_MAX_RANGE_RESULTS]; + long ts_msec; + int i; + struct input_dev *input =3D data->input_dev_ps; + + st_gettimeofday(&data->meas.comp_tv); + ts_msec =3D stmvl53lx_tv_dif(&data->start_tv, &data->meas.comp_tv)/1000; + + pmrange =3D &data->meas.multi_range_data; + tmprange =3D &data->meas.tmp_range_data; + + for (i =3D 0; i < VL53LX_MAX_RANGE_RESULTS; i++) + memcpy(&RangeData[i], &pmrange->RangeData[i], sizeof(VL53LX_TargetRangeD= ata_t)); + + data->meas.intr++; + + rc =3D VL53LX_GetMultiRangingData(&data->stdev, &data->meas.tmp_range_dat= a); + + if (tmprange->NumberOfObjectsFound =3D=3D 0) + tmprange->RangeData[0].RangeStatus =3D VL53LX_RANGESTATUS_NONE; + + memcpy(pmrange, tmprange, sizeof(VL53LX_MultiRangingData_t)); + + if (!rc) + rc =3D VL53LX_GetAdditionalData(&data->stdev, &data->meas.additional_dat= a); + detect_xtalk_value_change(data, pmrange); + + if (data->enable_sensor =3D=3D 0) { + vl53lx_dbgmsg("at meas #%d we got stopped\n", data->meas.cnt); + return; + } + if (rc) { + vl53lx_errmsg("VL53LX_GetRangingMeasurementData @%d %d", __LINE__, rc); + data->meas.err_cnt++; + data->meas.err_tot++; + if (data->meas.err_cnt > stvm531_get_max_meas_err(data) || + data->meas.err_tot > stvm531_get_max_stream_err(data)) { + vl53lx_errmsg("on #%d %d err %d tot stop", data->meas.cnt, data->meas.e= rr_cnt, data->meas.err_tot); + _ctrl_stop(data); + input_report_abs(input, ABS_MISC, ABNORMAL_STOP_3); + input_sync(input); + } + return; + } + + pmrange->TimeStamp =3D ts_msec; + for (i =3D 1; i < pmrange->NumberOfObjectsFound; i++) + pmrange->TimeStamp =3D ts_msec; + + data->meas.cnt++; + vl53lx_dbgmsg("#%3d %2d poll ts %5d status=3D%d obj cnt=3D%d\n", + data->meas.cnt, + data->meas.poll_cnt, + pmrange->TimeStamp, + pmrange->RangeData[0].RangeStatus, + pmrange->NumberOfObjectsFound); + + data->is_data_valid =3D true; + + wake_up_data_waiters(data); + + stmvl53lx_input_push_data(data); + stmvl53lx_insert_flush_events_lock(data); + + data->meas.start_tv =3D data->meas.comp_tv; + data->meas.poll_cnt =3D 0; + data->meas.err_cnt =3D 0; +} + +VL53LX_Error VL53LX_clear_interrupt_and_enable_next_range(VL53LX_DEV Dev, = uint8_t measurement_mode) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_and_start_range(Dev, measurement_mode, VL53LX_DEV= ICECONFIGLEVEL_GENERAL_ONWARDS); + + return status; +} + +VL53LX_Error VL53LX_ClearInterruptAndStartMeasurement(VL53LX_DEV Dev) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + uint8_t DeviceMeasurementMode; + + DeviceMeasurementMode =3D VL53LXDevDataGet(Dev, LLData.measurement_mode); + + Status =3D VL53LX_clear_interrupt_and_enable_next_range(Dev, DeviceMeasur= ementMode); + return Status; +} + +static int stmvl53lx_intr_process(struct stmvl53lx_data *data) +{ + uint8_t data_rdy; + int rc =3D 0; + struct st_timeval tv_now; + struct input_dev *input =3D data->input_dev_ps; + + if (!data->enable_sensor) + goto done; + + data->meas.poll_cnt++; + rc =3D VL53LX_GetMeasurementDataReady(&data->stdev, &data_rdy); + if (rc) { + vl53lx_errmsg("GetMeasurementDataReady @%d %d, fail\n", __LINE__, rc); + goto stop_io; + } + + if (!data_rdy) { + long poll_us; + + st_gettimeofday(&tv_now); + poll_us =3D stmvl53lx_tv_dif(&data->meas.start_tv, &tv_now); + if (poll_us > data->timing_budget*4) { + vl53lx_errmsg("we're polling %ld ms too long\n", poll_us/1000); + goto stop_io; + } + work_dbg("intr with no data rdy"); + goto done; + } + + if (data->is_first_irq) + data->is_first_irq =3D false; + else + stmvl53lx_on_newdata_event(data); + + if (data->enable_sensor) { + work_dbg("intr clr"); + data->is_delay_allowed =3D data->allow_hidden_start_stop; + rc =3D VL53LX_ClearInterruptAndStartMeasurement(&data->stdev); + data->is_delay_allowed =3D 0; + if (rc) { + vl53lx_errmsg("Cltr intr restart fail %d\n", rc); + goto stop_io; + } + } +done: + return rc; +stop_io: + vl53lx_errmsg("GetDatardy fail stop\n"); + _ctrl_stop(data); + input_report_abs(input, ABS_MISC, ABNORMAL_STOP_1); + input_sync(input); + return rc; +} + +int stmvl53lx_intr_handler(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + mutex_lock(&data->work_mutex); + if (data->enable_sensor) { + rc =3D stmvl53lx_intr_process(data); + } else { + vl53lx_dbgmsg("got intr but not on (dummy or calibration)\n"); + rc =3D 0; + } + + mutex_unlock(&data->work_mutex); + return rc; +} + +static irqreturn_t stmvl53lx_irq_handler_i2c(int vec, void *info) +{ + struct i2c_data *i2c_data =3D (struct i2c_data *)info; + + if (i2c_data->irq =3D=3D vec) { + modi2c_dbg("irq"); + stmvl53lx_intr_handler(i2c_data->vl53lx_data); + modi2c_dbg("over"); + } else { + if (!i2c_data->msg_flag.unhandled_irq_vec) { + modi2c_warn("unmatching vec %d !=3D %d\n", vec, i2c_data->irq); + i2c_data->msg_flag.unhandled_irq_vec =3D 1; + } + } + return IRQ_HANDLED; +} + +static void memory_release(struct kref *kref) +{ + struct i2c_data *data =3D container_of(kref, struct i2c_data, ref); + + vl53lx_dbgmsg("Enter\n"); + kfree(data->vl53lx_data); + kfree(data); + vl53lx_dbgmsg("End\n"); +} + +static int reset_release(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + if (!data->reset_state) + return 0; + + rc =3D stmvl53lx_module_func_tbl.reset_release(data->client_object); + if (rc) + vl53lx_errmsg("reset release fail rc=3D%d\n", rc); + else + data->reset_state =3D 0; + + return rc; +} + +static int stmvl53lx_start(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + data->is_first_irq =3D true; + data->is_data_valid =3D false; + data->is_xtalk_value_changed =3D false; + + rc =3D reset_release(data); + if (rc) + goto done; + + rc =3D stmvl53lx_sendparams(data); + if (rc) + goto done; + + st_gettimeofday(&data->start_tv); + data->meas.start_tv =3D data->start_tv; + kill_mz_data(&data->meas.multi_range_data); + + data->allow_hidden_start_stop =3D false; + + rc =3D VL53LX_StartMeasurement(&data->stdev); + if (rc) { + vl53lx_errmsg("VL53LX_StartMeasurement @%d fail %d", __LINE__, rc); + rc =3D store_last_error(data, rc); + goto done; + } + + data->meas.cnt =3D 0; + data->meas.err_cnt =3D 0; + data->meas.err_tot =3D 0; + data->meas.poll_cnt =3D 0; + data->meas.intr =3D 0; + data->enable_sensor =3D 1; + if (data->poll_mode) { + schedule_delayed_work(&data->dwork, msecs_to_jiffies(data->poll_delay_ms= )); + } + +done: + data->is_first_start_done =3D true; + return rc; +} + +static int ctrl_start(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + mutex_lock(&data->work_mutex); + + if (data->is_device_remove) { + rc =3D -ENODEV; + goto done; + } + + vl53lx_dbgmsg(" state =3D %d\n", data->enable_sensor); + if (data->enable_sensor =3D=3D 0 && !data->is_calibrating) { + rc =3D stmvl53lx_start(data); + } else { + rc =3D -EBUSY; + } + vl53lx_dbgmsg(" final state =3D %d\n", data->enable_sensor); +done: + mutex_unlock(&data->work_mutex); + return rc; +} + +static void stmvl53lx_insert_flush_events_lock(struct stmvl53lx_data *data) +{ + while (data->flush_todo_counter) { + data->flushCount++; + input_report_abs(data->input_dev_ps, ABS_GAS, data->flushCount); + input_sync(data->input_dev_ps); + vl53lx_dbgmsg("Sensor HAL Flush Count =3D %u\n", data->flushCount); + data->flush_todo_counter--; + } +} + +static int _ctrl_stop(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + vl53lx_dbgmsg("enter state =3D %d\n", data->enable_sensor); + data->is_data_valid =3D true; + if (data->enable_sensor =3D=3D 1) { + rc =3D stmvl53lx_stop(data); + } else { + vl53lx_dbgmsg("already off did nothing\n"); + rc =3D 0; + } + stmvl53lx_insert_flush_events_lock(data); + vl53lx_dbgmsg(" final state =3D %d\n", data->enable_sensor); + + return rc; +} + +static int ctrl_stop(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + mutex_lock(&data->work_mutex); + + if (data->is_device_remove) { + rc =3D -ENODEV; + goto done; + } + if (data->enable_sensor) + rc =3D _ctrl_stop(data); + else + rc =3D -EBUSY; +done: + mutex_unlock(&data->work_mutex); + return rc; +} + +static int ctrl_reg_access(struct stmvl53lx_data *data, void *p) +{ + struct stmvl53lx_register reg; + size_t total_byte; + int rc =3D 0; + + if (data->is_device_remove) + return -ENODEV; + + total_byte =3D offsetof(struct stmvl53lx_register, data.b); + if (copy_from_user(®, p, total_byte)) { + vl53lx_errmsg("%d, fail\n", __LINE__); + return -EFAULT; + } + + if (reg.cnt > STMVL53LX_MAX_CCI_XFER_SZ) { + vl53lx_errmsg("reg len %d > size limit\n", reg.cnt); + return -EINVAL; + } + + total_byte =3D offsetof(struct stmvl53lx_register, data.bytes[reg.cnt]); + if (!reg.is_read) { + if (copy_from_user(®, p, total_byte)) { + vl53lx_errmsg(" data cpy fail\n"); + return -EFAULT; + } + } + + if (!reg.is_read) { + rc =3D VL53LX_WriteMulti(&data->stdev, (uint16_t)reg.index, reg.data.byt= es, reg.cnt); + reg.status =3D rc; + total_byte =3D offsetof(struct stmvl53lx_register, data.b); + vl53lx_dbgmsg("wr %x %d bytes statu %d\n", reg.index, reg.cnt, rc); + if (rc) + rc =3D store_last_error(data, rc); + } else { + rc =3D VL53LX_ReadMulti(&data->stdev, (uint16_t)reg.index, reg.data.byte= s, reg.cnt); + reg.status =3D rc; + vl53lx_dbgmsg("rd %x %d bytes status %d\n", reg.index, reg.cnt, rc); + if (rc) { + total_byte =3D offsetof(struct stmvl53lx_register, data.b); + rc =3D store_last_error(data, rc); + } + } + + if (copy_to_user(p, ®, total_byte)) { + vl53lx_errmsg("%d, fail\n", __LINE__); + return -EFAULT; + } + return rc; +} + +static int reset_hold(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + if (data->reset_state) + return 0; + + if (data->force_device_on_en) + return 0; + + rc =3D stmvl53lx_module_func_tbl.reset_hold(data->client_object); + if (!rc) + data->reset_state =3D 1; + + return rc; +} + +static ssize_t stmvl53lx_show_enable_ps_sensor(struct device *dev, struct = device_attribute *attr, char *buf) +{ + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + return snprintf(buf, 5, "%d\n", data->enable_sensor); +} + +static ssize_t stmvl53lx_store_enable_ps_sensor(struct device *dev, struct= device_attribute *attr, const char *buf, size_t count) +{ + int rc =3D 0; + unsigned long val; + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + + rc =3D kstrtoul(buf, 10, &val); + if (rc) { + vl53lx_errmsg("enable sensor syntax in %s\n", buf); + return -EINVAL; + } + if (val =3D=3D 1) { + rc =3D ctrl_start(data); + } else if (val =3D=3D 0) { + rc =3D ctrl_stop(data); + } else { + vl53lx_dbgmsg("Unclog Input sub-system\n"); + input_report_abs(data->input_dev_ps, ABS_HAT0X, -1); + input_report_abs(data->input_dev_ps, ABS_HAT0Y, -1); + input_report_abs(data->input_dev_ps, ABS_HAT1X, -1); + input_report_abs(data->input_dev_ps, ABS_HAT1Y, -1); + input_report_abs(data->input_dev_ps, ABS_HAT2X, -1); + input_report_abs(data->input_dev_ps, ABS_HAT2Y, -1); + input_report_abs(data->input_dev_ps, ABS_HAT3X, -1); + input_report_abs(data->input_dev_ps, ABS_HAT3Y, -1); + input_report_abs(data->input_dev_ps, ABS_WHEEL, -1); + input_report_abs(data->input_dev_ps, ABS_BRAKE, -1); + input_report_abs(data->input_dev_ps, ABS_GAS, -1); + input_report_abs(data->input_dev_ps, ABS_TILT_X, -1); + input_report_abs(data->input_dev_ps, ABS_TILT_Y, -1); + input_report_abs(data->input_dev_ps, ABS_TOOL_WIDTH, -1); + input_report_abs(data->input_dev_ps, ABS_DISTANCE, -1); + input_report_abs(data->input_dev_ps, ABS_THROTTLE, -1); + input_report_abs(data->input_dev_ps, ABS_RUDDER, -1); + input_report_abs(data->input_dev_ps, ABS_MISC, -1); + input_report_abs(data->input_dev_ps, ABS_VOLUME, -1); + input_sync(data->input_dev_ps); + vl53lx_dbgmsg("Unclog the input sub-system\n"); + rc =3D 0; + } + vl53lx_dbgmsg("End\n"); + return rc ? rc : count; +} + +static DEVICE_ATTR(enable_ps_sensor, 0664, stmvl53lx_show_enable_ps_sensor= , stmvl53lx_store_enable_ps_sensor); + +static int stmvl53lx_set_poll_delay_ms(struct stmvl53lx_data *data, int de= lay) +{ + int rc =3D 0; + + if (delay <=3D 0) + rc =3D -EINVAL; + else + data->poll_delay_ms =3D delay; + + return rc; +} + +IMPLEMENT_PARAMETER_INTEGER(poll_delay_ms, "poll delay ms") + +static DEVICE_ATTR(set_delay_ms, 0660, stmvl53lx_show_poll_delay_ms, stmvl= 53lx_store_poll_delay_ms); + +static int stmvl53lx_set_timing_budget(struct stmvl53lx_data *data, int ti= ming) +{ + int rc =3D 0; + + if (timing <=3D 0) { + vl53lx_errmsg("invalid timing valid %d\n", timing); + rc =3D -EINVAL; + } else if (data->enable_sensor) { + rc =3D VL53LX_SetMeasurementTimingBudgetMicroSeconds(&data->stdev, + timing); + if (rc) { + vl53lx_errmsg("SetTimingBudget %d fail %d", timing, rc); + rc =3D store_last_error(data, rc); + } else + data->timing_budget =3D timing; + } else + data->timing_budget =3D timing; + + return rc; +} + +IMPLEMENT_PARAMETER_INTEGER(timing_budget, "timing budget") + +static DEVICE_ATTR(timing_budget, 0660, stmvl53lx_show_timing_budget, stmv= l53lx_store_timing_budget); + +static ssize_t stmvl53lx_show_roi(struct device *dev, struct device_attrib= ute *attr, char *buf) +{ + int n; + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + + mutex_lock(&data->work_mutex); + n =3D scnprintf(buf, PAGE_SIZE, "%d %d %d %d\n", data->roi_cfg.TopLeftX, = data->roi_cfg.TopLeftY, data->roi_cfg.BotRightX, data->roi_cfg.BotRightY); + mutex_unlock(&data->work_mutex); + return n; +} + +static ssize_t stmvl53lx_store_roi(struct device *dev, struct device_attri= bute *attr, const char *buf, size_t count) +{ + int rc; + int n; + int tlx, tly, brx, bry; + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + + mutex_lock(&data->work_mutex); + if (data->enable_sensor) { + vl53lx_errmsg("ERROR can't set roi while ranging"); + rc =3D -EBUSY; + } else { + n =3D sscanf(buf, "%d %d %d %d", &tlx, &tly, &brx, &bry); + if (n =3D=3D 4) { + data->roi_cfg.TopLeftX =3D tlx; + data->roi_cfg.TopLeftY =3D tly; + data->roi_cfg.BotRightX =3D brx; + data->roi_cfg.BotRightY =3D bry; + rc =3D count; + vl53lx_dbgmsg("ROI %2d %2d %2d %2d\n", (int)data->roi_cfg.TopLeftX, (in= t)data->roi_cfg.TopLeftY, (int)data->roi_cfg.BotRightX, (int)data->roi_cfg.= BotRightY); + } else { + vl53lx_errmsg("wrong roi syntax %s ", buf); + rc =3D -EINVAL; + } + } + mutex_unlock(&data->work_mutex); + vl53lx_dbgmsg("ret %d count %d\n", rc, (int)count); + + return rc; +} + +static DEVICE_ATTR(roi, 0660, stmvl53lx_show_roi, stmvl53lx_store_roi); + +static int stmvl53lx_set_distance_mode(struct stmvl53lx_data *data, + int distance_mode) +{ + int rc =3D 0; + + if (data->enable_sensor) { + vl53lx_errmsg("can't change distance mode while ranging\n"); + rc =3D -EBUSY; + } else { + switch (distance_mode) { + case VL53LX_DISTANCEMODE_SHORT: + case VL53LX_DISTANCEMODE_MEDIUM: + case VL53LX_DISTANCEMODE_LONG: + data->distance_mode =3D distance_mode; + break; + default: + vl53lx_errmsg("invalid distance mode %d\n", + distance_mode); + rc =3D -EINVAL; + break; + } + } + + return rc; +} + +IMPLEMENT_PARAMETER_INTEGER(distance_mode, "distance mode") + +static DEVICE_ATTR(distance_mode, 0660, stmvl53lx_show_distance_mode, stmv= l53lx_store_distance_mode); + +static int stmvl53lx_set_crosstalk_enable(struct stmvl53lx_data *data, + int crosstalk_enable) +{ + int rc =3D 0; + + if (data->enable_sensor) { + vl53lx_errmsg("can't change crosstalk enable while ranging\n"); + rc =3D -EBUSY; + } else if (crosstalk_enable =3D=3D 0 || crosstalk_enable =3D=3D 1) { + data->crosstalk_enable =3D crosstalk_enable; + } else { + vl53lx_errmsg("invalid crosstalk enable %d\n", + crosstalk_enable); + rc =3D -EINVAL; + } + + return rc; +} + +IMPLEMENT_PARAMETER_INTEGER(crosstalk_enable, "crosstalk enable") + +static DEVICE_ATTR(crosstalk_enable, 0660, stmvl53lx_show_crosstalk_enable= , stmvl53lx_store_crosstalk_enable); + +static int stmvl53lx_set_force_device_on_en(struct stmvl53lx_data *data, + int force_device_on_en) +{ + int rc =3D 0; + + if (force_device_on_en !=3D 0 && force_device_on_en !=3D 1) { + vl53lx_errmsg("invalid force_device_on_en mode %d\n", + force_device_on_en); + return -EINVAL; + } + + data->force_device_on_en =3D force_device_on_en; + + /* don't update reset if sensor is enable */ + if (data->enable_sensor) + return 0; + + /* ok update reset according force_device_on_en value */ + if (force_device_on_en) + rc =3D reset_release(data); + else + rc =3D reset_hold(data); + + return rc; +} + +IMPLEMENT_PARAMETER_INTEGER(force_device_on_en, "force device on enable") + + +static DEVICE_ATTR(force_device_on_enable, 0660, stmvl53lx_show_force_devi= ce_on_en, stmvl53lx_store_force_device_on_en); + +static int stmvl53lx_set_offset_correction_mode(struct stmvl53lx_data *dat= a, + int offset_correction_mode) +{ + int rc =3D 0; + + if (data->enable_sensor) { + vl53lx_errmsg( + "can't change offset correction mode while ranging\n"); + rc =3D -EBUSY; + } else { + switch (offset_correction_mode) { + case VL53LX_OFFSETCORRECTIONMODE_STANDARD: + case VL53LX_OFFSETCORRECTIONMODE_PERVCSEL: + data->offset_correction_mode =3D offset_correction_mode; + break; + default: + vl53lx_errmsg("invalid offset correction mode %d\n", + offset_correction_mode); + rc =3D -EINVAL; + break; + } + } + + return rc; +} + +IMPLEMENT_PARAMETER_INTEGER(offset_correction_mode, "offset correction mod= e") + +static DEVICE_ATTR(offset_correction_mode, 0660, stmvl53lx_show_offset_cor= rection_mode, stmvl53lx_store_offset_correction_mode); + +static ssize_t stmvl53lx_do_flush(struct device *dev, struct device_attrib= ute *attr, const char *buf, size_t count) +{ + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + + mutex_lock(&data->work_mutex); + + data->flush_todo_counter++; + if (data->enable_sensor =3D=3D 0) + stmvl53lx_insert_flush_events_lock(data); + + mutex_unlock(&data->work_mutex); + + return count; +} + +static DEVICE_ATTR(do_flush, 0660, NULL, stmvl53lx_do_flush); + +static ssize_t stmvl53lx_show_enable_debug(struct device *dev, struct devi= ce_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", stmvl53lx_enable_debug); +} + +static ssize_t stmvl53lx_store_enable_debug(struct device *dev, struct dev= ice_attribute *attr, const char *buf, size_t count) +{ + int enable_debug; + int rc =3D 0; + + if (kstrtoint(buf, 0, &enable_debug)) { + vl53lx_errmsg("invalid syntax in %s", buf); + rc =3D -EINVAL; + } else + stmvl53lx_enable_debug =3D enable_debug; + + return rc ? rc : count; +} + +static DEVICE_ATTR(enable_debug, 0660, stmvl53lx_show_enable_debug, stmvl5= 3lx_store_enable_debug); + +static ssize_t stmvl53lx_show_last_error_config(struct device *dev, struct= device_attribute *attr, char *buf) +{ + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + return scnprintf(buf, PAGE_SIZE, "%d\n", data->last_error); +} + +static DEVICE_ATTR(last_error, 0440, stmvl53lx_show_last_error_config, NUL= L); + +static ssize_t display_FixPoint1616(char *buf, size_t size, FixPoint1616_t= fix) +{ + uint32_t msb =3D fix >> 16; + uint32_t lsb =3D fix & 0xffff; + + lsb =3D (lsb * 1000000ULL + 32768) / 65536; + + return scnprintf(buf, size, "%d.%06d", msb, (uint32_t) lsb); +} + +static ssize_t stmvl53lx_show_optical_center_config(struct device *dev, st= ruct device_attribute *attr, char *buf) +{ + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + ssize_t res =3D 0; + + res +=3D display_FixPoint1616(&buf[res], PAGE_SIZE - res, data->optical_o= ffset_x); + res +=3D scnprintf(&buf[res], PAGE_SIZE - res, " "); + res +=3D display_FixPoint1616(&buf[res], PAGE_SIZE - res, data->optical_o= ffset_y); + res +=3D scnprintf(&buf[res], PAGE_SIZE - res, "\n"); + return res; +} + +static DEVICE_ATTR(optical_center, 0440, stmvl53lx_show_optical_center_con= fig, NULL); + +VL53LX_Error VL53LX_set_tuning_parm(VL53LX_DEV Dev, VL53LX_TuningParms tun= ing_parm_key, int32_t tuning_parm_value) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_hist_post_process_config_t *pHP =3D &(pdev->histpostprocess); + VL53LX_xtalkextract_config_t *pXC =3D &(pdev->xtalk_extract_cfg); + + switch (tuning_parm_key) { + case VL53LX_TUNINGPARM_VERSION: + pdev->tuning_parms.tp_tuning_parm_version =3D (uint16_t)tuning_parm_valu= e; + break; + case VL53LX_TUNINGPARM_KEY_TABLE_VERSION: + pdev->tuning_parms.tp_tuning_parm_key_table_version =3D (uint16_t)tuning= _parm_value; + if ((uint16_t)tuning_parm_value !=3D VL53LX_TUNINGPARM_KEY_TABLE_VERSION= _DEFAULT) + status =3D VL53LX_ERROR_TUNING_PARM_KEY_MISMATCH; + break; + case VL53LX_TUNINGPARM_LLD_VERSION: + pdev->tuning_parms.tp_tuning_parm_lld_version =3D (uint16_t)tuning_parm_= value; + break; + case VL53LX_TUNINGPARM_HIST_ALGO_SELECT: + pHP->hist_algo_select =3D (VL53LX_HistAlgoSelect)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_TARGET_ORDER: + pHP->hist_target_order =3D (VL53LX_HistTargetOrder)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_FILTER_WOI_0: + pHP->filter_woi0 =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_FILTER_WOI_1: + pHP->filter_woi1 =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD: + pHP->hist_amb_est_method =3D (VL53LX_HistAmbEstMethod)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0: + pHP->ambient_thresh_sigma0 =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1: + pHP->ambient_thresh_sigma1 =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS: + pHP->min_ambient_thresh_events =3D (int32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER: + pHP->ambient_thresh_events_scaler =3D (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD: + pHP->noise_threshold =3D (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT: + pHP->signal_total_events_limit =3D (int32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM: + pHP->sigma_estimator__sigma_ref_mm =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM: + pHP->sigma_thresh =3D (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_GAIN_FACTOR: + pdev->gain_cal.histogram_ranging_gain_factor =3D (uint16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE: + pHP->algo__consistency_check__phase_tolerance =3D (uint8_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM: + pHP->algo__consistency_check__min_max_tolerance =3D (uint16_t)tuning_par= m_value; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA: + pHP->algo__consistency_check__event_sigma =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT: + pHP->algo__consistency_check__event_min_spad_count =3D (uint16_t)tuning_= parm_value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_hist_long =3D (uint8_t)tuning_parm_= value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_hist_med =3D (uint8_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_hist_short =3D (uint8_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE: + pdev->tuning_parms.tp_init_phase_ref_hist_long =3D (uint8_t)tuning_parm_= value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE: + pdev->tuning_parms.tp_init_phase_ref_hist_med =3D (uint8_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE: + pdev->tuning_parms.tp_init_phase_ref_hist_short =3D (uint8_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM: + pdev->xtalk_cfg.algo__crosstalk_detect_min_valid_range_mm =3D (int16_t)t= uning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM: + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm =3D (int16_t)t= uning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM: + pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm =3D (uint16_t)tuning= _parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE: + pHP->algo__crosstalk_detect_min_max_tolerance =3D (uint16_t)tuning_parm_= value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS: + pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps =3D (uint16_t= )tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA: + pHP->algo__crosstalk_detect_event_sigma =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS: + pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps =3D (int16_t)tuning= _parm_value; + break; + case VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE: + pdev->tuning_parms.tp_consistency_lite_phase_tolerance =3D (uint8_t)tuni= ng_parm_value; + break; + case VL53LX_TUNINGPARM_PHASECAL_TARGET: + pdev->tuning_parms.tp_phasecal_target =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE: + pdev->tuning_parms.tp_cal_repeat_rate =3D (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR: + pdev->gain_cal.standard_ranging_gain_factor =3D (uint16_t)tuning_parm_va= lue; + break; + case VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM: + pdev->tuning_parms.tp_lite_min_clip =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM: + pdev->tuning_parms.tp_lite_long_sigma_thresh_mm =3D (uint16_t)tuning_par= m_value; + break; + case VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM: + pdev->tuning_parms.tp_lite_med_sigma_thresh_mm =3D (uint16_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM: + pdev->tuning_parms.tp_lite_short_sigma_thresh_mm =3D (uint16_t)tuning_pa= rm_value; + break; + case VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS: + pdev->tuning_parms.tp_lite_long_min_count_rate_rtn_mcps =3D (uint16_t)tu= ning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS: + pdev->tuning_parms.tp_lite_med_min_count_rate_rtn_mcps =3D (uint16_t)tun= ing_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS: + pdev->tuning_parms.tp_lite_short_min_count_rate_rtn_mcps =3D (uint16_t)t= uning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH: + pdev->tuning_parms.tp_lite_sigma_est_pulse_width_ns =3D (uint8_t)tuning_= parm_value; + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS: + pdev->tuning_parms.tp_lite_sigma_est_amb_width_ns =3D (uint8_t)tuning_pa= rm_value; + break; + case VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM: + pdev->tuning_parms.tp_lite_sigma_ref_mm =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_RIT_MULT: + pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult =3D (uint8_t)tunin= g_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_SEED_CONFIG: + pdev->tuning_parms.tp_lite_seed_cfg =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_QUANTIFIER: + pdev->tuning_parms.tp_lite_quantifier =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT: + pdev->tuning_parms.tp_lite_first_order_select =3D (uint8_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS: + pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps =3D (int16_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_lite_long =3D (uint8_t)tuning_parm_= value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_lite_med =3D (uint8_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE: + pdev->tuning_parms.tp_init_phase_rtn_lite_short =3D (uint8_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE: + pdev->tuning_parms.tp_init_phase_ref_lite_long =3D (uint8_t)tuning_parm_= value; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE: + pdev->tuning_parms.tp_init_phase_ref_lite_med =3D (uint8_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE: + pdev->tuning_parms.tp_init_phase_ref_lite_short =3D (uint8_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_TIMED_SEED_CONFIG: + pdev->tuning_parms.tp_timed_seed_cfg =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA: + pdev->dmax_cfg.signal_thresh_sigma =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0: + pdev->dmax_cfg.target_reflectance_for_dmax_calc[0] =3D (uint16_t)tuning_= parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1: + pdev->dmax_cfg.target_reflectance_for_dmax_calc[1] =3D (uint16_t)tuning_= parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2: + pdev->dmax_cfg.target_reflectance_for_dmax_calc[2] =3D (uint16_t)tuning_= parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3: + pdev->dmax_cfg.target_reflectance_for_dmax_calc[3] =3D (uint16_t)tuning_= parm_value; + break; + case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4: + pdev->dmax_cfg.target_reflectance_for_dmax_calc[4] =3D (uint16_t)tuning_= parm_value; + break; + case VL53LX_TUNINGPARM_VHV_LOOPBOUND: + pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =3D (uint8_t)tuning= _parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE: + pdev->refspadchar.device_test_mode =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD: + pdev->refspadchar.VL53LX_p_005 =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US: + pdev->refspadchar.timeout_us =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS: + pdev->refspadchar.target_count_rate_mcps =3D (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS: + pdev->refspadchar.min_count_rate_limit_mcps =3D (uint16_t)tuning_parm_va= lue; + break; + case VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS: + pdev->refspadchar.max_count_rate_limit_mcps =3D (uint16_t)tuning_parm_va= lue; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES: + pXC->num_of_samples =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM: + pXC->algo__crosstalk_extract_min_valid_range_mm =3D (int16_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM: + pXC->algo__crosstalk_extract_max_valid_range_mm =3D (int16_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS: + pXC->dss_config__target_total_rate_mcps =3D (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US: + pXC->phasecal_config_timeout_us =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS: + pXC->algo__crosstalk_extract_max_valid_rate_kcps =3D (uint16_t)tuning_p= arm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM: + pXC->algo__crosstalk_extract_max_sigma_mm =3D (uint16_t)tuning_parm_valu= e; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US: + pXC->mm_config_timeout_us =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US: + pXC->range_config_timeout_us =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS: + pdev->offsetcal_cfg.dss_config__target_total_rate_mcps =3D (uint16_t)tun= ing_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US: + pdev->offsetcal_cfg.phasecal_config_timeout_us =3D (uint32_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US: + pdev->offsetcal_cfg.mm_config_timeout_us =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US: + pdev->offsetcal_cfg.range_config_timeout_us =3D (uint32_t)tuning_parm_va= lue; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES: + pdev->offsetcal_cfg.pre_num_of_samples =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES: + pdev->offsetcal_cfg.mm1_num_of_samples =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES: + pdev->offsetcal_cfg.mm2_num_of_samples =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS: + pdev->zonecal_cfg.dss_config__target_total_rate_mcps =3D (uint16_t)tunin= g_parm_value; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US: + pdev->zonecal_cfg.phasecal_config_timeout_us =3D (uint32_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US: + pdev->zonecal_cfg.mm_config_timeout_us =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES: + pdev->zonecal_cfg.phasecal_num_of_samples =3D (uint16_t)tuning_parm_valu= e; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US: + pdev->zonecal_cfg.range_config_timeout_us =3D (uint32_t)tuning_parm_valu= e; + break; + case VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES: + pdev->zonecal_cfg.zone_num_of_samples =3D (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD: + pdev->ssc_cfg.VL53LX_p_005 =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_SPADMAP_VCSEL_START: + pdev->ssc_cfg.vcsel_start =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS: + pdev->ssc_cfg.rate_limit_mcps =3D (uint16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + pdev->tuning_parms.tp_dss_target_lite_mcps =3D (uint16_t)tuning_parm_val= ue; + break; + case VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + pdev->tuning_parms.tp_dss_target_histo_mcps =3D (uint16_t)tuning_parm_va= lue; + break; + case VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + pdev->tuning_parms.tp_dss_target_histo_mz_mcps =3D (uint16_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS: + pdev->tuning_parms.tp_dss_target_timed_mcps =3D (uint16_t)tuning_parm_va= lue; + break; + case VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_lite_us =3D (uint32_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_hist_long_us =3D (uint32_t)tuning= _parm_value; + break; + case VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_hist_med_us =3D (uint32_t)tuning_= parm_value; + break; + case VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_hist_short_us =3D (uint32_t)tunin= g_parm_value; + break; + case VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_mz_long_us =3D (uint32_t)tuning_p= arm_value; + break; + case VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_mz_med_us =3D (uint32_t)tuning_pa= rm_value; + break; + case VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_mz_short_us =3D (uint32_t)tuning_= parm_value; + break; + case VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_phasecal_timeout_timed_us =3D (uint32_t)tuning_par= m_value; + break; + case VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_mm_timeout_lite_us =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_mm_timeout_histo_us =3D (uint32_t)tuning_parm_valu= e; + break; + case VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_mm_timeout_mz_us =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_mm_timeout_timed_us =3D (uint32_t)tuning_parm_valu= e; + break; + case VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_range_timeout_lite_us =3D (uint32_t)tuning_parm_va= lue; + break; + case VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_range_timeout_histo_us =3D (uint32_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_range_timeout_mz_us =3D (uint32_t)tuning_parm_valu= e; + break; + case VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_range_timeout_timed_us =3D (uint32_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN: + pdev->smudge_correct_config.smudge_margin =3D (uint16_t)tuning_parm_valu= e; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN: + pdev->smudge_correct_config.noise_margin =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT: + pdev->smudge_correct_config.user_xtalk_offset_limit =3D (uint32_t)tuning= _parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI: + pdev->smudge_correct_config.user_xtalk_offset_limit_hi =3D (uint8_t)tuni= ng_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT: + pdev->smudge_correct_config.sample_limit =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA: + pdev->smudge_correct_config.single_xtalk_delta =3D (uint32_t)tuning_parm= _value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA: + pdev->smudge_correct_config.averaged_xtalk_delta =3D (uint32_t)tuning_pa= rm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT: + pdev->smudge_correct_config.smudge_corr_clip_limit =3D (uint32_t)tuning_= parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SCALER_CALC_METHOD: + pdev->smudge_correct_config.scaler_calc_method =3D (uint8_t)tuning_parm_= value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER: + pdev->smudge_correct_config.x_gradient_scaler =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER: + pdev->smudge_correct_config.y_gradient_scaler =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET: + pdev->smudge_correct_config.user_scaler_set =3D (uint8_t)tuning_parm_val= ue; + break; + case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY: + pdev->smudge_correct_config.smudge_corr_single_apply =3D (uint8_t)tuning= _parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD: + pdev->smudge_correct_config.smudge_corr_ambient_threshold =3D (uint32_t)= tuning_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS: + pdev->smudge_correct_config.nodetect_ambient_threshold =3D (uint32_t)tun= ing_parm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT: + pdev->smudge_correct_config.nodetect_sample_limit =3D (uint32_t)tuning_p= arm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS: + pdev->smudge_correct_config.nodetect_xtalk_offset =3D (uint32_t)tuning_p= arm_value; + break; + case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM: + pdev->smudge_correct_config.nodetect_min_range_mm =3D (uint16_t)tuning_p= arm_value; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND: + pdev->low_power_auto_data.vhv_loop_bound =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_mm_timeout_lpa_us =3D (uint32_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US: + pdev->tuning_parms.tp_range_timeout_lpa_us =3D (uint32_t)tuning_parm_val= ue; + break; + case VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS: + pdev->tuning_parms.tp_dss_target_very_short_mcps =3D (uint16_t)tuning_pa= rm_value; + break; + case VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER: + pdev->tuning_parms.tp_phasecal_patch_power =3D (uint16_t) tuning_parm_va= lue; + break; + case VL53LX_TUNINGPARM_HIST_MERGE: + pdev->tuning_parms.tp_hist_merge =3D (uint16_t) tuning_parm_value; + break; + case VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD: + pdev->tuning_parms.tp_reset_merge_threshold =3D (uint16_t) tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE: + pdev->tuning_parms.tp_hist_merge_max_size =3D (uint16_t) tuning_parm_val= ue; + break; + case VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR: + pdev->smudge_correct_config.max_smudge_factor =3D (uint32_t)tuning_parm_= value; + break; + case VL53LX_TUNINGPARM_UWR_ENABLE: + pdev->tuning_parms.tp_uwr_enable =3D (uint8_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MIN: + pdev->tuning_parms.tp_uwr_med_z_1_min =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MAX: + pdev->tuning_parms.tp_uwr_med_z_1_max =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MIN: + pdev->tuning_parms.tp_uwr_med_z_2_min =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MAX: + pdev->tuning_parms.tp_uwr_med_z_2_max =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MIN: + pdev->tuning_parms.tp_uwr_med_z_3_min =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MAX: + pdev->tuning_parms.tp_uwr_med_z_3_max =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MIN: + pdev->tuning_parms.tp_uwr_med_z_4_min =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MAX: + pdev->tuning_parms.tp_uwr_med_z_4_max =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MIN: + pdev->tuning_parms.tp_uwr_med_z_5_min =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MAX: + pdev->tuning_parms.tp_uwr_med_z_5_max =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEA: + pdev->tuning_parms.tp_uwr_med_corr_z_1_rangea =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEB: + pdev->tuning_parms.tp_uwr_med_corr_z_1_rangeb =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEA: + pdev->tuning_parms.tp_uwr_med_corr_z_2_rangea =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEB: + pdev->tuning_parms.tp_uwr_med_corr_z_2_rangeb =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEA: + pdev->tuning_parms.tp_uwr_med_corr_z_3_rangea =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEB: + pdev->tuning_parms.tp_uwr_med_corr_z_3_rangeb =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEA: + pdev->tuning_parms.tp_uwr_med_corr_z_4_rangea =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEB: + pdev->tuning_parms.tp_uwr_med_corr_z_4_rangeb =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEA: + pdev->tuning_parms.tp_uwr_med_corr_z_5_rangea =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEB: + pdev->tuning_parms.tp_uwr_med_corr_z_5_rangeb =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MIN: + pdev->tuning_parms.tp_uwr_lng_z_1_min =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MAX: + pdev->tuning_parms.tp_uwr_lng_z_1_max =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MIN: + pdev->tuning_parms.tp_uwr_lng_z_2_min =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MAX: + pdev->tuning_parms.tp_uwr_lng_z_2_max =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MIN: + pdev->tuning_parms.tp_uwr_lng_z_3_min =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MAX: + pdev->tuning_parms.tp_uwr_lng_z_3_max =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MIN: + pdev->tuning_parms.tp_uwr_lng_z_4_min =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MAX: + pdev->tuning_parms.tp_uwr_lng_z_4_max =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MIN: + pdev->tuning_parms.tp_uwr_lng_z_5_min =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MAX: + pdev->tuning_parms.tp_uwr_lng_z_5_max =3D (int16_t)tuning_parm_value; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEA: + pdev->tuning_parms.tp_uwr_lng_corr_z_1_rangea =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEB: + pdev->tuning_parms.tp_uwr_lng_corr_z_1_rangeb =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEA: + pdev->tuning_parms.tp_uwr_lng_corr_z_2_rangea =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEB: + pdev->tuning_parms.tp_uwr_lng_corr_z_2_rangeb =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEA: + pdev->tuning_parms.tp_uwr_lng_corr_z_3_rangea =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEB: + pdev->tuning_parms.tp_uwr_lng_corr_z_3_rangeb =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEA: + pdev->tuning_parms.tp_uwr_lng_corr_z_4_rangea =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEB: + pdev->tuning_parms.tp_uwr_lng_corr_z_4_rangeb =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEA: + pdev->tuning_parms.tp_uwr_lng_corr_z_5_rangea =3D (int16_t)tuning_parm_v= alue; + break; + case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEB: + pdev->tuning_parms.tp_uwr_lng_corr_z_5_rangeb =3D (int16_t)tuning_parm_v= alue; + break; + default: + status =3D VL53LX_ERROR_INVALID_PARAMS; + break; + } + return status; +} + +VL53LX_Error VL53LX_SetTuningParameter(VL53LX_DEV Dev, uint16_t TuningPara= meterId, int32_t TuningParameterValue) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + if (TuningParameterId =3D=3D VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OF= FSET_KCPS) + return VL53LX_ERROR_INVALID_PARAMS; + + if (TuningParameterId >=3D 32768) + Status =3D VL53LX_set_tuning_parm(Dev, TuningParameterId, TuningParamete= rValue); + else { + if (TuningParameterId < VL53LX_TUNING_MAX_TUNABLE_KEY) + BDTable[TuningParameterId] =3D TuningParameterValue; + else + Status =3D VL53LX_ERROR_INVALID_PARAMS; + } + + return Status; +} + +static int stmvl53lx_set_tuning(struct stmvl53lx_data *data, int key, int = value) +{ + int rc =3D 0; + + if (data->enable_sensor) { + vl53lx_errmsg("can't change tuning params while ranging\n"); + return -EBUSY; + } + + if (data->is_calibrating) { + vl53lx_errmsg("can't change tuning params while calibrating\n"); + return -EBUSY; + } + + if (key & ~0xffff) + return -EINVAL; + + vl53lx_dbgmsg("trying to set %d with key %d", value, key); + + rc =3D VL53LX_SetTuningParameter(&data->stdev, key, value); + if (rc) + rc =3D store_last_error(data, rc); + + return rc; +} + +static ssize_t stmvl53lx_store_tuning(struct device *dev, struct device_at= tribute *attr, const char *buf, size_t count) +{ + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + int key; + int value; + int n; + int rc =3D 0; + + mutex_lock(&data->work_mutex); + + n =3D sscanf(buf, "%d %d", &key, &value); + if (n !=3D 2) { + rc =3D -EINVAL; + goto error; + } + rc =3D stmvl53lx_set_tuning(data, key, value); + if (rc) + goto error; + + mutex_unlock(&data->work_mutex); + + return count; + +error: + mutex_unlock(&data->work_mutex); + return rc; +} + +static DEVICE_ATTR(tuning, 0220, NULL, stmvl53lx_store_tuning); + +VL53LX_Error VL53LX_GetTuningParameter(VL53LX_DEV Dev, uint16_t TuningPara= meterId, int32_t *pTuningParameterValue) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + if (TuningParameterId >=3D 32768) + Status =3D VL53LX_get_tuning_parm(Dev, TuningParameterId, pTuningParamet= erValue); + else { + if (TuningParameterId < VL53LX_TUNING_MAX_TUNABLE_KEY) + *pTuningParameterValue =3D BDTable[TuningParameterId]; + else + Status =3D VL53LX_ERROR_INVALID_PARAMS; + } + + return Status; +} + +static int stmvl53lx_display_tuning_key(struct stmvl53lx_data *data, char = *buf, int *pos, int key) +{ + int rc =3D 0; + int value =3D 0; + int sz; + + rc =3D VL53LX_GetTuningParameter(&data->stdev, key, &value); + if (rc) + return 0; + + sz =3D snprintf(&buf[*pos], PAGE_SIZE - *pos, "%d %d\n", key, value); + if (sz >=3D PAGE_SIZE - *pos) + return -ENOSPC; + + *pos +=3D sz; + + return 0; +} + +static ssize_t stmvl53lx_show_tuning_status(struct device *dev, struct dev= ice_attribute *attr, char *buf) +{ + const int max_tuning_key =3D 65535; + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + int rc =3D 0; + int i; + int pos =3D 0; + + mutex_lock(&data->work_mutex); + + for (i =3D 0; i < max_tuning_key; ++i) { + rc =3D stmvl53lx_display_tuning_key(data, buf, &pos, i); + if (rc) + break; + } + + mutex_unlock(&data->work_mutex); + + return rc ? rc : pos; +} + +static DEVICE_ATTR(tuning_status, 0440, stmvl53lx_show_tuning_status, NULL= ); + +static int stmvl53lx_set_smudge_correction_mode(struct stmvl53lx_data *dat= a, + int smudge_correction_mode) +{ + int rc =3D 0; + + if (data->enable_sensor) { + vl53lx_errmsg("can't change smudge corr mode while ranging\n"); + rc =3D -EBUSY; + } else { + switch (smudge_correction_mode) { + case VL53LX_SMUDGE_CORRECTION_NONE: + case VL53LX_SMUDGE_CORRECTION_CONTINUOUS: + case VL53LX_SMUDGE_CORRECTION_SINGLE: + case VL53LX_SMUDGE_CORRECTION_DEBUG: + data->smudge_correction_mode =3D smudge_correction_mode; + break; + default: + vl53lx_errmsg("invalid smudge correction mode %d\n", + smudge_correction_mode); + rc =3D -EINVAL; + break; + } + } + + return rc; +} + +IMPLEMENT_PARAMETER_INTEGER(smudge_correction_mode, "smudge correction mod= e") + +static DEVICE_ATTR(smudge_correction_mode, 0660, stmvl53lx_show_smudge_cor= rection_mode, stmvl53lx_store_smudge_correction_mode); + +static ssize_t stmvl53lx_show_is_xtalk_value_changed_config(struct device = *dev, struct device_attribute *attr, char *buf) +{ + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + int param; + + mutex_lock(&data->work_mutex); + param =3D data->is_xtalk_value_changed; + mutex_unlock(&data->work_mutex); + + return scnprintf(buf, PAGE_SIZE, "%d\n", param); +} + +static DEVICE_ATTR(is_xtalk_value_changed, 0440, stmvl53lx_show_is_xtalk_v= alue_changed_config, NULL); + +static struct attribute *stmvl53lx_attributes[] =3D { + &dev_attr_enable_ps_sensor.attr, + &dev_attr_set_delay_ms.attr, + &dev_attr_timing_budget.attr, + &dev_attr_roi.attr, + &dev_attr_do_flush.attr, + &dev_attr_distance_mode.attr, + &dev_attr_crosstalk_enable.attr, + &dev_attr_enable_debug.attr, + &dev_attr_force_device_on_enable.attr, + &dev_attr_last_error.attr, + &dev_attr_offset_correction_mode.attr, + &dev_attr_optical_center.attr, + &dev_attr_tuning.attr, + &dev_attr_tuning_status.attr, + &dev_attr_smudge_correction_mode.attr, + &dev_attr_is_xtalk_value_changed.attr, + NULL +}; + +static const struct attribute_group stmvl53lx_attr_group =3D { + .attrs =3D stmvl53lx_attributes, +}; + +static int ctrl_param_last_error(struct stmvl53lx_data *data, struct stmvl= 53lx_parameter *param) +{ + int rc =3D 0; + + if (param->is_read) { + param->value =3D data->last_error; + param->status =3D 0; + vl53lx_dbgmsg("get last error %d", param->value); + rc =3D 0; + } else { + rc =3D -EINVAL; + } + + return rc; +} + +static int ctrl_param_optical_center(struct stmvl53lx_data *data, struct s= tmvl53lx_parameter *param) +{ + if (!param->is_read) + return -EINVAL; + + param->value =3D data->optical_offset_x; + param->value2 =3D data->optical_offset_y; + + return 0; +} + +static int ctrl_param_tuning(struct stmvl53lx_data *data, struct stmvl53lx= _parameter *param) +{ + if (param->is_read) + return -EINVAL; + + return stmvl53lx_set_tuning(data, param->value, param->value2); +} + +static int ctrl_param_is_xtalk_value_changed(struct stmvl53lx_data *data, = struct stmvl53lx_parameter *param) +{ + if (!param->is_read) + return -EINVAL; + + param->value =3D data->is_xtalk_value_changed; + + return 0; +} + +static int ctrl_params(struct stmvl53lx_data *data, void __user *p) +{ + int rc, rc2; + struct stmvl53lx_parameter param; + + mutex_lock(&data->work_mutex); + + if (data->is_device_remove) { + rc =3D -ENODEV; + goto done; + } + rc =3D copy_from_user(¶m, p, sizeof(param)); + param.status =3D 0; + if (rc) { + rc =3D -EFAULT; + goto done; + } + switch (param.name) { + case VL53LX_POLLDELAY_PAR: + rc =3D ctrl_param_poll_delay_ms(data, ¶m); + break; + case VL53LX_TIMINGBUDGET_PAR: + rc =3D ctrl_param_timing_budget(data, ¶m); + break; + case VL53LX_DISTANCEMODE_PAR: + rc =3D ctrl_param_distance_mode(data, ¶m); + break; + case VL53LX_XTALKENABLE_PAR: + rc =3D ctrl_param_crosstalk_enable(data, ¶m); + break; + case VL53LX_FORCEDEVICEONEN_PAR: + rc =3D ctrl_param_force_device_on_en(data, ¶m); + break; + case VL53LX_LASTERROR_PAR: + rc =3D ctrl_param_last_error(data, ¶m); + break; + case VL53LX_OFFSETCORRECTIONMODE_PAR: + rc =3D ctrl_param_offset_correction_mode(data, ¶m); + break; + case VL53LX_OPTICALCENTER_PAR: + rc =3D ctrl_param_optical_center(data, ¶m); + break; + case VL53LX_TUNING_PAR: + rc =3D ctrl_param_tuning(data, ¶m); + break; + case VL53LX_SMUDGECORRECTIONMODE_PAR: + rc =3D ctrl_param_smudge_correction_mode(data, ¶m); + break; + case VL53LX_ISXTALKVALUECHANGED_PAR: + rc =3D ctrl_param_is_xtalk_value_changed(data, ¶m); + break; + default: + vl53lx_errmsg("unknown or unsupported %d\n", param.name); + rc =3D -EINVAL; + } + + if (param.is_read && rc =3D=3D 0) { + rc2 =3D copy_to_user(p, ¶m, sizeof(param)); + if (rc2) { + rc =3D -EFAULT; + vl53lx_errmsg("copy to user fail %d\n", rc); + } + } +done: + mutex_unlock(&data->work_mutex); + return rc; +} + +VL53LX_Error VL53LX_set_part_to_part_data(VL53LX_DEV Dev, VL53LX_calibrati= on_data_t *pcal_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_xtalk_config_t *pC =3D &(pdev->xtalk_cfg); + VL53LX_hist_post_process_config_t *pHP =3D &(pdev->histpostprocess); + VL53LX_customer_nvm_managed_t *pN =3D &(pdev->customer); + uint32_t tempu32; + + if (pcal_data->struct_version !=3D VL53LX_LL_CALIBRATION_DATA_STRUCT_VERS= ION) { + status =3D VL53LX_ERROR_INVALID_PARAMS; + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + memcpy(&(pdev->customer), &(pcal_data->customer), sizeof(VL53LX_customer= _nvm_managed_t)); + memcpy(&(pdev->add_off_cal_data), &(pcal_data->add_off_cal_data), sizeof= (VL53LX_additional_offset_cal_data_t)); + memcpy(&(pdev->fmt_dmax_cal), &(pcal_data->fmt_dmax_cal), sizeof(VL53LX_= dmax_calibration_data_t)); + memcpy(&(pdev->cust_dmax_cal), &(pcal_data->cust_dmax_cal), sizeof(VL53L= X_dmax_calibration_data_t)); + memcpy(&(pdev->xtalk_shapes), &(pcal_data->xtalkhisto), sizeof(VL53LX_xt= alk_histogram_data_t)); + memcpy(&(pdev->gain_cal), &(pcal_data->gain_cal), sizeof(VL53LX_gain_cal= ibration_data_t)); + memcpy(&(pdev->cal_peak_rate_map), &(pcal_data->cal_peak_rate_map), size= of(VL53LX_cal_peak_rate_map_t)); + memcpy(&(pdev->per_vcsel_cal_data), &(pcal_data->per_vcsel_cal_data), si= zeof(VL53LX_per_vcsel_period_offset_cal_data_t)); + + pC->algo__crosstalk_compensation_plane_offset_kcps =3D pN->algo__crossta= lk_compensation_plane_offset_kcps; + pC->algo__crosstalk_compensation_x_plane_gradient_kcps =3D pN->algo__cro= sstalk_compensation_x_plane_gradient_kcps; + pC->algo__crosstalk_compensation_y_plane_gradient_kcps =3D pN->algo__cro= sstalk_compensation_y_plane_gradient_kcps; + + pHP->algo__crosstalk_compensation_plane_offset_kcps =3D VL53LX_calc_cros= stalk_plane_offset_with_margin(pC->algo__crosstalk_compensation_plane_offse= t_kcps, pC->histogram_mode_crosstalk_margin_kcps); + + pHP->algo__crosstalk_compensation_x_plane_gradient_kcps =3D pC->algo__cr= osstalk_compensation_x_plane_gradient_kcps; + pHP->algo__crosstalk_compensation_y_plane_gradient_kcps =3D pC->algo__cr= osstalk_compensation_y_plane_gradient_kcps; + + if (pC->global_crosstalk_compensation_enable =3D=3D 0x00) { + pN->algo__crosstalk_compensation_plane_offset_kcps =3D 0x00; + pN->algo__crosstalk_compensation_x_plane_gradient_kcps =3D 0x00; + pN->algo__crosstalk_compensation_y_plane_gradient_kcps =3D 0x00; + } else { + tempu32 =3D VL53LX_calc_crosstalk_plane_offset_with_margin(pC->algo__cr= osstalk_compensation_plane_offset_kcps, pC->lite_mode_crosstalk_margin_kcps= ); + if (tempu32 > 0xFFFF) + tempu32 =3D 0xFFFF; + + pN->algo__crosstalk_compensation_plane_offset_kcps =3D (uint16_t)tempu3= 2; + } + } + return status; +} + +VL53LX_Error VL53LX_get_current_xtalk_settings(VL53LX_DEV Dev, VL53LX_xtal= k_calibration_results_t *pxtalk) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t i; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pxtalk->algo__crosstalk_compensation_plane_offset_kcps =3D pdev->xtalk_cf= g.algo__crosstalk_compensation_plane_offset_kcps; + pxtalk->algo__crosstalk_compensation_x_plane_gradient_kcps =3D pdev->xtal= k_cfg.algo__crosstalk_compensation_x_plane_gradient_kcps; + pxtalk->algo__crosstalk_compensation_y_plane_gradient_kcps =3D pdev->xtal= k_cfg.algo__crosstalk_compensation_y_plane_gradient_kcps; + for (i =3D 0; i < VL53LX_BIN_REC_SIZE; i++) + pxtalk->algo__xtalk_cpo_HistoMerge_kcps[i] =3D pdev->xtalk_cal.algo__xta= lk_cpo_HistoMerge_kcps[i]; + + return status; +} + +VL53LX_Error VL53LX_set_current_xtalk_settings(VL53LX_DEV Dev, VL53LX_xtal= k_calibration_results_t *pxtalk) +{ + uint8_t i; + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->xtalk_cfg.algo__crosstalk_compensation_plane_offset_kcps =3D pxtalk= ->algo__crosstalk_compensation_plane_offset_kcps; + pdev->xtalk_cfg.algo__crosstalk_compensation_x_plane_gradient_kcps =3D px= talk->algo__crosstalk_compensation_x_plane_gradient_kcps; + pdev->xtalk_cfg.algo__crosstalk_compensation_y_plane_gradient_kcps =3D px= talk->algo__crosstalk_compensation_y_plane_gradient_kcps; + for (i =3D 0; i < VL53LX_BIN_REC_SIZE; i++) + pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[i] =3D pxtalk->algo__xta= lk_cpo_HistoMerge_kcps[i]; + + return status; +} + +VL53LX_Error VL53LX_SetCalibrationData(VL53LX_DEV Dev, VL53LX_CalibrationD= ata_t *pCalibrationData) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_CustomerNvmManaged_t *pC; + VL53LX_calibration_data_t cal_data; + uint32_t x; + VL53LX_xtalk_calibration_results_t xtalk; + + cal_data.struct_version =3D pCalibrationData->struct_version - VL53LX_ADD= ITIONAL_CALIBRATION_DATA_STRUCT_VERSION; + + memcpy(&(cal_data.add_off_cal_data), &(pCalibrationData->add_off_cal_data= ), sizeof(VL53LX_additional_offset_cal_data_t)); + memcpy(&(cal_data.optical_centre), &(pCalibrationData->optical_centre), s= izeof(VL53LX_optical_centre_t)); + memcpy(&(cal_data.xtalkhisto), &(pCalibrationData->xtalkhisto), sizeof(VL= 53LX_xtalk_histogram_data_t)); + memcpy(&(cal_data.gain_cal), &(pCalibrationData->gain_cal), sizeof(VL53LX= _gain_calibration_data_t)); + memcpy(&(cal_data.cal_peak_rate_map), &(pCalibrationData->cal_peak_rate_m= ap), sizeof(VL53LX_cal_peak_rate_map_t)); + memcpy(&(cal_data.per_vcsel_cal_data), &(pCalibrationData->per_vcsel_cal_= data), sizeof(VL53LX_per_vcsel_period_offset_cal_data_t)); + + pC =3D &pCalibrationData->customer; + x =3D pC->algo__crosstalk_compensation_plane_offset_kcps; + cal_data.customer.algo__crosstalk_compensation_plane_offset_kcps =3D (uin= t16_t)(x&0x0000FFFF); + + cal_data.customer.global_config__spad_enables_ref_0 =3D pC->global_config= __spad_enables_ref_0; + cal_data.customer.global_config__spad_enables_ref_1 =3D pC->global_config= __spad_enables_ref_1; + cal_data.customer.global_config__spad_enables_ref_2 =3D pC->global_config= __spad_enables_ref_2; + cal_data.customer.global_config__spad_enables_ref_3 =3D pC->global_config= __spad_enables_ref_3; + cal_data.customer.global_config__spad_enables_ref_4 =3D pC->global_config= __spad_enables_ref_4; + cal_data.customer.global_config__spad_enables_ref_5 =3D pC->global_config= __spad_enables_ref_5; + cal_data.customer.global_config__ref_en_start_select =3D pC->global_confi= g__ref_en_start_select; + cal_data.customer.ref_spad_man__num_requested_ref_spads =3D pC->ref_spad_= man__num_requested_ref_spads; + cal_data.customer.ref_spad_man__ref_location =3D pC->ref_spad_man__ref_lo= cation; + cal_data.customer.algo__crosstalk_compensation_x_plane_gradient_kcps =3D = pC->algo__crosstalk_compensation_x_plane_gradient_kcps; + cal_data.customer.algo__crosstalk_compensation_y_plane_gradient_kcps =3D = pC->algo__crosstalk_compensation_y_plane_gradient_kcps; + cal_data.customer.ref_spad_char__total_rate_target_mcps =3D pC->ref_spad_= char__total_rate_target_mcps; + cal_data.customer.algo__part_to_part_range_offset_mm =3D pC->algo__part_t= o_part_range_offset_mm; + cal_data.customer.mm_config__inner_offset_mm =3D pC->mm_config__inner_off= set_mm; + cal_data.customer.mm_config__outer_offset_mm =3D pC->mm_config__outer_off= set_mm; + + Status =3D VL53LX_set_part_to_part_data(Dev, &cal_data); + + if (Status !=3D VL53LX_ERROR_NONE) + goto ENDFUNC; + + Status =3D VL53LX_get_current_xtalk_settings(Dev, &xtalk); + + if (Status !=3D VL53LX_ERROR_NONE) + goto ENDFUNC; + + xtalk.algo__crosstalk_compensation_plane_offset_kcps =3D x; + + Status =3D VL53LX_set_tuning_parm(Dev, VL53LX_TUNINGPARM_DYNXTALK_NODETEC= T_XTALK_OFFSET_KCPS, x); + + memcpy(&(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]), &(pCalibrationData->a= lgo__xtalk_cpo_HistoMerge_kcps[0]), sizeof(pCalibrationData->algo__xtalk_cp= o_HistoMerge_kcps)); + + Status =3D VL53LX_set_current_xtalk_settings(Dev, &xtalk); + +ENDFUNC: + return Status; + +} + +VL53LX_Error VL53LX_get_part_to_part_data(VL53LX_DEV Dev, VL53LX_calibrati= on_data_t *pcal_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_xtalk_config_t *pC =3D &(pdev->xtalk_cfg); + VL53LX_customer_nvm_managed_t *pCN =3D &(pcal_data->customer); + + pcal_data->struct_version =3D VL53LX_LL_CALIBRATION_DATA_STRUCT_VERSION; + memcpy(&(pcal_data->customer), &(pdev->customer), sizeof(VL53LX_customer_= nvm_managed_t)); + + if (pC->algo__crosstalk_compensation_plane_offset_kcps > 0xFFFF) { + pCN->algo__crosstalk_compensation_plane_offset_kcps =3D 0xFFFF; + } else { + pCN->algo__crosstalk_compensation_plane_offset_kcps =3D (uint16_t)pC->al= go__crosstalk_compensation_plane_offset_kcps; + } + pCN->algo__crosstalk_compensation_x_plane_gradient_kcps =3D pC->algo__cro= sstalk_compensation_x_plane_gradient_kcps; + pCN->algo__crosstalk_compensation_y_plane_gradient_kcps =3D pC->algo__cro= sstalk_compensation_y_plane_gradient_kcps; + + memcpy(&(pcal_data->fmt_dmax_cal), &(pdev->fmt_dmax_cal), sizeof(VL53LX_d= max_calibration_data_t)); + memcpy(&(pcal_data->cust_dmax_cal), &(pdev->cust_dmax_cal), sizeof(VL53LX= _dmax_calibration_data_t)); + memcpy(&(pcal_data->add_off_cal_data), &(pdev->add_off_cal_data), sizeof(= VL53LX_additional_offset_cal_data_t)); + memcpy(&(pcal_data->optical_centre), &(pdev->optical_centre), sizeof(VL53= LX_optical_centre_t)); + memcpy(&(pcal_data->xtalkhisto), &(pdev->xtalk_shapes), sizeof(VL53LX_xta= lk_histogram_data_t)); + memcpy(&(pcal_data->gain_cal), &(pdev->gain_cal), sizeof(VL53LX_gain_cali= bration_data_t)); + memcpy(&(pcal_data->cal_peak_rate_map), &(pdev->cal_peak_rate_map), sizeo= f(VL53LX_cal_peak_rate_map_t)); + memcpy(&(pcal_data->per_vcsel_cal_data), &(pdev->per_vcsel_cal_data), siz= eof(VL53LX_per_vcsel_period_offset_cal_data_t)); + + return status; +} + +VL53LX_Error VL53LX_GetCalibrationData(VL53LX_DEV Dev, VL53LX_CalibrationD= ata_t *pCalibrationData) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_calibration_data_t cal_data; + VL53LX_CustomerNvmManaged_t *pC; + VL53LX_customer_nvm_managed_t *pC2; + VL53LX_xtalk_calibration_results_t xtalk; + uint32_t tmp; + + Status =3D VL53LX_get_part_to_part_data(Dev, &cal_data); + + pCalibrationData->struct_version =3D cal_data.struct_version + VL53LX_ADD= ITIONAL_CALIBRATION_DATA_STRUCT_VERSION; + + memcpy(&(pCalibrationData->add_off_cal_data), &(cal_data.add_off_cal_data= ), sizeof(VL53LX_additional_offset_cal_data_t)); + memcpy(&(pCalibrationData->optical_centre), &(cal_data.optical_centre), s= izeof(VL53LX_optical_centre_t)); + memcpy(&(pCalibrationData->xtalkhisto), &(cal_data.xtalkhisto), sizeof(VL= 53LX_xtalk_histogram_data_t)); + memcpy(&(pCalibrationData->gain_cal), &(cal_data.gain_cal), sizeof(VL53LX= _gain_calibration_data_t)); + memcpy(&(pCalibrationData->cal_peak_rate_map), &(cal_data.cal_peak_rate_m= ap), sizeof(VL53LX_cal_peak_rate_map_t)); + memcpy(&(pCalibrationData->per_vcsel_cal_data), &(cal_data.per_vcsel_cal_= data), sizeof(VL53LX_per_vcsel_period_offset_cal_data_t)); + + pC =3D &pCalibrationData->customer; + pC2 =3D &cal_data.customer; + pC->global_config__spad_enables_ref_0 =3D pC2->global_config__spad_enable= s_ref_0; + pC->global_config__spad_enables_ref_1 =3D pC2->global_config__spad_enable= s_ref_1; + pC->global_config__spad_enables_ref_2 =3D pC2->global_config__spad_enable= s_ref_2; + pC->global_config__spad_enables_ref_3 =3D pC2->global_config__spad_enable= s_ref_3; + pC->global_config__spad_enables_ref_4 =3D pC2->global_config__spad_enable= s_ref_4; + pC->global_config__spad_enables_ref_5 =3D pC2->global_config__spad_enable= s_ref_5; + pC->global_config__ref_en_start_select =3D pC2->global_config__ref_en_sta= rt_select; + pC->ref_spad_man__num_requested_ref_spads =3D pC2->ref_spad_man__num_requ= ested_ref_spads; + pC->ref_spad_man__ref_location =3D pC2->ref_spad_man__ref_location; + pC->algo__crosstalk_compensation_x_plane_gradient_kcps =3D pC2->algo__cro= sstalk_compensation_x_plane_gradient_kcps; + pC->algo__crosstalk_compensation_y_plane_gradient_kcps =3D pC2->algo__cro= sstalk_compensation_y_plane_gradient_kcps; + pC->ref_spad_char__total_rate_target_mcps =3D pC2->ref_spad_char__total_r= ate_target_mcps; + pC->algo__part_to_part_range_offset_mm =3D pC2->algo__part_to_part_range_= offset_mm; + pC->mm_config__inner_offset_mm =3D pC2->mm_config__inner_offset_mm; + pC->mm_config__outer_offset_mm =3D pC2->mm_config__outer_offset_mm; + + pC->algo__crosstalk_compensation_plane_offset_kcps =3D (uint32_t)(pC2->al= go__crosstalk_compensation_plane_offset_kcps); + + Status =3D VL53LX_get_current_xtalk_settings(Dev, &xtalk); + + if (Status !=3D VL53LX_ERROR_NONE) + goto ENDFUNC; + + tmp =3D xtalk.algo__crosstalk_compensation_plane_offset_kcps; + pC->algo__crosstalk_compensation_plane_offset_kcps =3D tmp; + tmp =3D xtalk.algo__crosstalk_compensation_x_plane_gradient_kcps; + pC->algo__crosstalk_compensation_x_plane_gradient_kcps =3D tmp; + tmp =3D xtalk.algo__crosstalk_compensation_y_plane_gradient_kcps; + pC->algo__crosstalk_compensation_y_plane_gradient_kcps =3D tmp; + + memcpy(&(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]), &(xtalk.a= lgo__xtalk_cpo_HistoMerge_kcps[0]), sizeof(pCalibrationData->algo__xtalk_cp= o_HistoMerge_kcps)); + +ENDFUNC: + return Status; +} + +static ssize_t stmvl53lx_calib_data_read(struct file *filp, struct kobject= *kobj, const struct bin_attribute *attr, char *buf, loff_t off, size_t cou= nt) +{ + struct device *dev =3D container_of(kobj, struct device, kobj); + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + VL53LX_CalibrationData_t calib; + int rc =3D 0; + void *src =3D (void *) &calib; + + mutex_lock(&data->work_mutex); + + vl53lx_dbgmsg("off =3D %lld / count =3D %d", off, count); + + if (off < 0 || off > sizeof(VL53LX_CalibrationData_t)) + goto invalid; + + memset(&calib, 0, sizeof(calib)); + rc =3D VL53LX_GetCalibrationData(&data->stdev, &calib); + if (rc) { + vl53lx_errmsg("VL53LX_GetCalibrationData fail %d", rc); + rc =3D store_last_error(data, rc); + goto error; + } + + if (off + count > sizeof(VL53LX_CalibrationData_t)) + count =3D sizeof(VL53LX_CalibrationData_t) - off; + memcpy(buf, src + off, count); + + mutex_unlock(&data->work_mutex); + return count; + +invalid: + vl53lx_errmsg("invalid syntax"); + rc =3D -EINVAL; + goto error; + +error: + mutex_unlock(&data->work_mutex); + return rc; +} + +static ssize_t stmvl53lx_calib_data_write(struct file *filp, struct kobjec= t *kobj, const struct bin_attribute *attr, char *buf, loff_t off, size_t co= unt) +{ + int rc =3D 0; + struct device *dev =3D container_of(kobj, struct device, kobj); + struct stmvl53lx_data *data =3D dev_get_drvdata(dev); + + mutex_lock(&data->work_mutex); + + vl53lx_dbgmsg("off =3D %lld / count =3D %d", off, count); + + if (data->enable_sensor) { + rc =3D -EBUSY; + vl53lx_errmsg("can't set calib data while ranging\n"); + goto error; + } + + if (off !=3D 0 || count !=3D sizeof(VL53LX_CalibrationData_t)) + goto invalid; + + rc =3D VL53LX_SetCalibrationData(&data->stdev, (VL53LX_CalibrationData_t = *) buf); + if (rc) { + vl53lx_errmsg("VL53LX_SetCalibrationData fail %d", rc); + rc =3D store_last_error(data, rc); + goto error; + } + + mutex_unlock(&data->work_mutex); + return count; + +invalid: + vl53lx_errmsg("invalid syntax"); + rc =3D -EINVAL; + goto error; + +error: + mutex_unlock(&data->work_mutex); + + return rc; +} + +static struct bin_attribute stmvl53lx_calib_data_attr =3D { + .attr =3D { + .name =3D "calibration_data", + .mode =3D 0660, + }, + .size =3D sizeof(VL53LX_CalibrationData_t), + .read =3D stmvl53lx_calib_data_read, + .write =3D stmvl53lx_calib_data_write, +}; + +void VL53LX_init_version(VL53LX_DEV Dev) +{ + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->version.ll_major =3D VL53LX_LL_API_IMPLEMENTATION_VER_MAJOR; + pdev->version.ll_minor =3D VL53LX_LL_API_IMPLEMENTATION_VER_MINOR; + pdev->version.ll_build =3D VL53LX_LL_API_IMPLEMENTATION_VER_SUB; + pdev->version.ll_revision =3D VL53LX_LL_API_IMPLEMENTATION_VER_REVISION; +} + +VL53LX_Error VL53LX_get_static_nvm_managed(VL53LX_DEV Dev, VL53LX_static_n= vm_managed_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES]; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_ReadMulti(Dev, VL53LX_I2C_SLAVE__DEVICE_ADDRESS, comms= _buffer, VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_i2c_decode_static_nvm_managed(VL53LX_STATIC_NVM_MANAGE= D_I2C_SIZE_BYTES, comms_buffer, pdata); + + return status; +} + +VL53LX_Error VL53LX_i2c_decode_customer_nvm_managed(uint16_t buf_size, uin= t8_t *pbuffer, VL53LX_customer_nvm_managed_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + pdata->global_config__spad_enables_ref_0 =3D (*(pbuffer + 0)); + pdata->global_config__spad_enables_ref_1 =3D (*(pbuffer + 1)); + pdata->global_config__spad_enables_ref_2 =3D (*(pbuffer + 2)); + pdata->global_config__spad_enables_ref_3 =3D (*(pbuffer + 3)); + pdata->global_config__spad_enables_ref_4 =3D (*(pbuffer + 4)); + pdata->global_config__spad_enables_ref_5 =3D (*(pbuffer + 5)) & 0xF; + pdata->global_config__ref_en_start_select =3D (*(pbuffer + 6)); + pdata->ref_spad_man__num_requested_ref_spads =3D (*(pbuffer + 7)) & 0x3= F; + pdata->ref_spad_man__ref_location =3D (*(pbuffer + 8)) & 0x3; + pdata->algo__crosstalk_compensation_plane_offset_kcps =3D (VL53LX_i2c_dec= ode_uint16_t(2, pbuffer + 9)); + pdata->algo__crosstalk_compensation_x_plane_gradient_kcps =3D (VL53LX_i2c= _decode_int16_t(2, pbuffer + 11)); + pdata->algo__crosstalk_compensation_y_plane_gradient_kcps =3D (VL53LX_i2c= _decode_int16_t(2, pbuffer + 13)); + pdata->ref_spad_char__total_rate_target_mcps =3D (VL53LX_i2c_decode_uint1= 6_t(2, pbuffer + 15)); + pdata->algo__part_to_part_range_offset_mm =3D (VL53LX_i2c_decode_int16_t(= 2, pbuffer + 17)) & 0x1FFF; + pdata->mm_config__inner_offset_mm =3D (VL53LX_i2c_decode_int16_t(2, pbuff= er + 19)); + pdata->mm_config__outer_offset_mm =3D (VL53LX_i2c_decode_int16_t(2, pbuff= er + 21)); + + return status; +} + +VL53LX_Error VL53LX_get_customer_nvm_managed(VL53LX_DEV Dev, VL53LX_custom= er_nvm_managed_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES]; + int16_t offset; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_ReadMulti(Dev, VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_= 0, comms_buffer, VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_i2c_decode_customer_nvm_managed(VL53LX_CUSTOMER_NVM_MA= NAGED_I2C_SIZE_BYTES, comms_buffer, pdata); + + if (status =3D=3D VL53LX_ERROR_NONE) { + offset =3D pdata->algo__part_to_part_range_offset_mm; + offset =3D offset / 4; + if (offset >=3D 1024) + offset -=3D 2048; + pdata->algo__part_to_part_range_offset_mm =3D 0; + pdata->mm_config__inner_offset_mm =3D offset; + pdata->mm_config__outer_offset_mm =3D offset; + } + + return status; +} + +VL53LX_Error VL53LX_i2c_decode_nvm_copy_data(uint16_t buf_size, uint8_t *p= buffer, VL53LX_nvm_copy_data_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + pdata->identification__model_id =3D (*(pbuffer + 0)); + pdata->identification__module_type =3D (*(pbuffer + 1)); + pdata->identification__revision_id =3D (*(pbuffer + 2)); + pdata->identification__module_id =3D (VL53LX_i2c_decode_uint16_t(2, pbuff= er + 3)); + pdata->ana_config__fast_osc__trim_max =3D (*(pbuffer + 5)) & 0x7F; + pdata->ana_config__fast_osc__freq_set =3D (*(pbuffer + 6)) & 0x7; + pdata->ana_config__vcsel_trim =3D (*(pbuffer + 7)) & 0x7; + pdata->ana_config__vcsel_selion =3D (*(pbuffer + 8)) & 0x3F; + pdata->ana_config__vcsel_selion_max =3D (*(pbuffer + 9)) & 0x3F; + pdata->protected_laser_safety__lock_bit =3D (*(pbuffer + 10)) & 0x1; + pdata->laser_safety__key =3D (*(pbuffer + 11)) & 0x7F; + pdata->laser_safety__key_ro =3D (*(pbuffer + 12)) & 0x1; + pdata->laser_safety__clip =3D (*(pbuffer + 13)) & 0x3F; + pdata->laser_safety__mult =3D (*(pbuffer + 14)) & 0x3F; + pdata->global_config__spad_enables_rtn_0 =3D (*(pbuffer + 15)); + pdata->global_config__spad_enables_rtn_1 =3D (*(pbuffer + 16)); + pdata->global_config__spad_enables_rtn_2 =3D (*(pbuffer + 17)); + pdata->global_config__spad_enables_rtn_3 =3D (*(pbuffer + 18)); + pdata->global_config__spad_enables_rtn_4 =3D (*(pbuffer + 19)); + pdata->global_config__spad_enables_rtn_5 =3D (*(pbuffer + 20)); + pdata->global_config__spad_enables_rtn_6 =3D (*(pbuffer + 21)); + pdata->global_config__spad_enables_rtn_7 =3D (*(pbuffer + 22)); + pdata->global_config__spad_enables_rtn_8 =3D (*(pbuffer + 23)); + pdata->global_config__spad_enables_rtn_9 =3D (*(pbuffer + 24)); + pdata->global_config__spad_enables_rtn_10 =3D (*(pbuffer + 25)); + pdata->global_config__spad_enables_rtn_11 =3D (*(pbuffer + 26)); + pdata->global_config__spad_enables_rtn_12 =3D (*(pbuffer + 27)); + pdata->global_config__spad_enables_rtn_13 =3D (*(pbuffer + 28)); + pdata->global_config__spad_enables_rtn_14 =3D (*(pbuffer + 29)); + pdata->global_config__spad_enables_rtn_15 =3D (*(pbuffer + 30)); + pdata->global_config__spad_enables_rtn_16 =3D (*(pbuffer + 31)); + pdata->global_config__spad_enables_rtn_17 =3D (*(pbuffer + 32)); + pdata->global_config__spad_enables_rtn_18 =3D (*(pbuffer + 33)); + pdata->global_config__spad_enables_rtn_19 =3D (*(pbuffer + 34)); + pdata->global_config__spad_enables_rtn_20 =3D (*(pbuffer + 35)); + pdata->global_config__spad_enables_rtn_21 =3D (*(pbuffer + 36)); + pdata->global_config__spad_enables_rtn_22 =3D (*(pbuffer + 37)); + pdata->global_config__spad_enables_rtn_23 =3D (*(pbuffer + 38)); + pdata->global_config__spad_enables_rtn_24 =3D (*(pbuffer + 39)); + pdata->global_config__spad_enables_rtn_25 =3D (*(pbuffer + 40)); + pdata->global_config__spad_enables_rtn_26 =3D (*(pbuffer + 41)); + pdata->global_config__spad_enables_rtn_27 =3D (*(pbuffer + 42)); + pdata->global_config__spad_enables_rtn_28 =3D (*(pbuffer + 43)); + pdata->global_config__spad_enables_rtn_29 =3D (*(pbuffer + 44)); + pdata->global_config__spad_enables_rtn_30 =3D (*(pbuffer + 45)); + pdata->global_config__spad_enables_rtn_31 =3D (*(pbuffer + 46)); + pdata->roi_config__mode_roi_centre_spad =3D (*(pbuffer + 47)); + pdata->roi_config__mode_roi_xy_size =3D (*(pbuffer + 48)); + + return status; +} + +VL53LX_Error VL53LX_get_nvm_copy_data(VL53LX_DEV Dev, VL53LX_nvm_copy_data= _t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t comms_buffer[VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES]; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_ReadMulti(Dev, VL53LX_IDENTIFICATION__MODEL_ID, comms_= buffer, VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_i2c_decode_nvm_copy_data(VL53LX_NVM_COPY_DATA_I2C_SIZE= _BYTES, comms_buffer, pdata); + + return status; +} + +void VL53LX_copy_rtn_good_spads_to_buffer(VL53LX_nvm_copy_data_t *pdata, u= int8_t *pbuffer) +{ + *(pbuffer + 0) =3D pdata->global_config__spad_enables_rtn_0; + *(pbuffer + 1) =3D pdata->global_config__spad_enables_rtn_1; + *(pbuffer + 2) =3D pdata->global_config__spad_enables_rtn_2; + *(pbuffer + 3) =3D pdata->global_config__spad_enables_rtn_3; + *(pbuffer + 4) =3D pdata->global_config__spad_enables_rtn_4; + *(pbuffer + 5) =3D pdata->global_config__spad_enables_rtn_5; + *(pbuffer + 6) =3D pdata->global_config__spad_enables_rtn_6; + *(pbuffer + 7) =3D pdata->global_config__spad_enables_rtn_7; + *(pbuffer + 8) =3D pdata->global_config__spad_enables_rtn_8; + *(pbuffer + 9) =3D pdata->global_config__spad_enables_rtn_9; + *(pbuffer + 10) =3D pdata->global_config__spad_enables_rtn_10; + *(pbuffer + 11) =3D pdata->global_config__spad_enables_rtn_11; + *(pbuffer + 12) =3D pdata->global_config__spad_enables_rtn_12; + *(pbuffer + 13) =3D pdata->global_config__spad_enables_rtn_13; + *(pbuffer + 14) =3D pdata->global_config__spad_enables_rtn_14; + *(pbuffer + 15) =3D pdata->global_config__spad_enables_rtn_15; + *(pbuffer + 16) =3D pdata->global_config__spad_enables_rtn_16; + *(pbuffer + 17) =3D pdata->global_config__spad_enables_rtn_17; + *(pbuffer + 18) =3D pdata->global_config__spad_enables_rtn_18; + *(pbuffer + 19) =3D pdata->global_config__spad_enables_rtn_19; + *(pbuffer + 20) =3D pdata->global_config__spad_enables_rtn_20; + *(pbuffer + 21) =3D pdata->global_config__spad_enables_rtn_21; + *(pbuffer + 22) =3D pdata->global_config__spad_enables_rtn_22; + *(pbuffer + 23) =3D pdata->global_config__spad_enables_rtn_23; + *(pbuffer + 24) =3D pdata->global_config__spad_enables_rtn_24; + *(pbuffer + 25) =3D pdata->global_config__spad_enables_rtn_25; + *(pbuffer + 26) =3D pdata->global_config__spad_enables_rtn_26; + *(pbuffer + 27) =3D pdata->global_config__spad_enables_rtn_27; + *(pbuffer + 28) =3D pdata->global_config__spad_enables_rtn_28; + *(pbuffer + 29) =3D pdata->global_config__spad_enables_rtn_29; + *(pbuffer + 30) =3D pdata->global_config__spad_enables_rtn_30; + *(pbuffer + 31) =3D pdata->global_config__spad_enables_rtn_31; +} + +VL53LX_Error VL53LX_set_firmware_enable_register(VL53LX_DEV Dev, uint8_t v= alue) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->sys_ctrl.firmware__enable =3D value; + + status =3D VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, pdev->sys_ctrl.fir= mware__enable); + + return status; +} + +VL53LX_Error VL53LX_disable_firmware(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + status =3D VL53LX_set_firmware_enable_register(Dev, 0x00); + + return status; +} + +VL53LX_Error VL53LX_nvm_enable(VL53LX_DEV Dev, uint16_t nvm_ctrl_pulse_wid= th, int32_t nvm_power_up_delay_us) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_disable_firmware(Dev); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_enable_powerforce(Dev); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WaitUs(Dev, VL53LX_ENABLE_POWERFORCE_SETTLING_TIME_US); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__PDN, 0x01); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__CLK_CTRL1, 0x05); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WaitUs(Dev, nvm_power_up_delay_us); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__MODE, 0x01); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrWord(Dev, VL53LX_RANGING_CORE__NVM_CTRL__PULSE_WIDTH= _MSB, nvm_ctrl_pulse_width); + + return status; +} + + +VL53LX_Error VL53LX_nvm_read(VL53LX_DEV Dev, uint8_t start_address, uint8_= t count, uint8_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t nvm_addr =3D 0; + + for (nvm_addr =3D start_address; + nvm_addr < (start_address+count) ; nvm_addr++) { + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__ADDR, nvm_= addr); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__READN, 0x0= 0); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WaitUs(Dev, VL53LX_NVM_READ_TRIGGER_DELAY_US); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__READN, 0x0= 1); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_ReadMulti(Dev, VL53LX_RANGING_CORE__NVM_CTRL__DATAOUT= _MMM, pdata, 4); + + pdata =3D pdata + 4; + } + return status; +} + +VL53LX_Error VL53LX_enable_firmware(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + status =3D VL53LX_set_firmware_enable_register(Dev, 0x01); + + return status; +} + +VL53LX_Error VL53LX_nvm_disable(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__READN, 0x01= ); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__PDN, 0x00); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_disable_powerforce(Dev); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_enable_firmware(Dev); + + return status; +} + +VL53LX_Error VL53LX_read_nvm_raw_data(VL53LX_DEV Dev, uint8_t start_addres= s, uint8_t count, uint8_t *pnvm_raw_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_nvm_enable(Dev, 0x0004, VL53LX_NVM_POWER_UP_DELAY_US); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_nvm_read(Dev, start_address, count, pnvm_raw_data); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_nvm_disable(Dev); + + return status; +} + +VL53LX_Error VL53LX_nvm_decode_optical_centre(uint16_t buf_size, uint8_t *= pbuffer, VL53LX_optical_centre_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint16_t tmp =3D 0; + + if (buf_size < VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE) + return VL53LX_ERROR_BUFFER_TOO_SMALL; + + tmp =3D 0x0100; + tmp -=3D (uint16_t)*(pbuffer + 2); + if (tmp > 0x0FF) + tmp =3D 0; + + pdata->x_centre =3D (uint8_t)tmp; + pdata->y_centre =3D *(pbuffer + 3); + + return status; +} + +VL53LX_Error VL53LX_read_nvm_optical_centre(VL53LX_DEV Dev, VL53LX_optical= _centre_t *pcentre) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t nvm_data[VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE]; + + status =3D VL53LX_read_nvm_raw_data(Dev, (uint8_t)(VL53LX_NVM__FMT__OPTIC= AL_CENTRE_DATA_INDEX >> 2), (uint8_t)(VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_= SIZE >> 2), nvm_data); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_nvm_decode_optical_centre(VL53LX_NVM__FMT__OPTICAL_CEN= TRE_DATA_SIZE, nvm_data, pcentre); + + return status; +} + +VL53LX_Error VL53LX_nvm_decode_cal_peak_rate_map(uint16_t buf_size, uint8_= t *pbuffer, VL53LX_cal_peak_rate_map_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + uint8_t *ptmp =3D NULL; + uint8_t i =3D 0; + + if (buf_size < VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE) + return VL53LX_ERROR_BUFFER_TOO_SMALL; + + pdata->cal_distance_mm =3D (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffe= r); + + pdata->cal_reflectance_pc =3D (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbu= ffer + 2); + pdata->cal_reflectance_pc =3D pdata->cal_reflectance_pc >> 6; + + pdata->max_samples =3D VL53LX_NVM_PEAK_RATE_MAP_SAMPLES; + pdata->width =3D VL53LX_NVM_PEAK_RATE_MAP_WIDTH; + pdata->height =3D VL53LX_NVM_PEAK_RATE_MAP_HEIGHT; + + ptmp =3D pbuffer + 4; + for (i =3D 0 ; i < VL53LX_NVM_PEAK_RATE_MAP_SAMPLES ; i++) { + pdata->peak_rate_mcps[i] =3D (uint16_t)VL53LX_i2c_decode_uint16_t(2, ptm= p); + ptmp +=3D 2; + } + + return status; +} + +VL53LX_Error VL53LX_read_nvm_cal_peak_rate_map(VL53LX_DEV Dev, VL53LX_cal_= peak_rate_map_t *pcal_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t nvm_data[VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE]; + + status =3D VL53LX_read_nvm_raw_data(Dev, (uint8_t)(VL53LX_NVM__FMT__CAL_P= EAK_RATE_MAP_DATA_INDEX >> 2), (uint8_t)(VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP= _DATA_SIZE >> 2), nvm_data); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_nvm_decode_cal_peak_rate_map(VL53LX_NVM__FMT__CAL_PEAK= _RATE_MAP_DATA_SIZE, nvm_data, pcal_data); + + return status; +} + +VL53LX_Error VL53LX_nvm_decode_additional_offset_cal_data(uint16_t buf_siz= e, uint8_t *pbuffer, VL53LX_additional_offset_cal_data_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + if (buf_size < VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE) + return VL53LX_ERROR_BUFFER_TOO_SMALL; + + pdata->result__mm_inner_actual_effective_spads =3D (uint16_t)VL53LX_i2c_d= ecode_uint16_t(2, pbuffer); + pdata->result__mm_outer_actual_effective_spads =3D (uint16_t)VL53LX_i2c_d= ecode_uint16_t(2, pbuffer + 2); + pdata->result__mm_inner_peak_signal_count_rtn_mcps =3D (uint16_t)VL53LX_i= 2c_decode_uint16_t(2, pbuffer + 4); + pdata->result__mm_outer_peak_signal_count_rtn_mcps =3D (uint16_t)VL53LX_i= 2c_decode_uint16_t(2, pbuffer + 6); + + return status; +} + +VL53LX_Error VL53LX_read_nvm_additional_offset_cal_data(VL53LX_DEV Dev, VL= 53LX_additional_offset_cal_data_t *pcal_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t nvm_data[VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE]; + + status =3D VL53LX_read_nvm_raw_data(Dev, (uint8_t)(VL53LX_NVM__FMT__ADDIT= IONAL_OFFSET_CAL_DATA_INDEX >> 2), (uint8_t)(VL53LX_NVM__FMT__ADDITIONAL_OF= FSET_CAL_DATA_SIZE >> 2), nvm_data); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_nvm_decode_additional_offset_cal_data(VL53LX_NVM__FMT_= _ADDITIONAL_OFFSET_CAL_DATA_SIZE, nvm_data, pcal_data); + + return status; +} + +void VL53LX_spad_number_to_byte_bit_index(uint8_t spad_number, uint8_t *pb= yte_index, uint8_t *pbit_index, uint8_t *pbit_mask) +{ + *pbyte_index =3D spad_number >> 3; + *pbit_index =3D spad_number & 0x07; + *pbit_mask =3D 0x01 << *pbit_index; +} + +uint8_t VL53LX_is_aperture_location(uint8_t row, uint8_t col) +{ + uint8_t is_aperture =3D 0; + uint8_t mod_row =3D row % 4; + uint8_t mod_col =3D col % 4; + + if (mod_row =3D=3D 0 && mod_col =3D=3D 2) + is_aperture =3D 1; + + if (mod_row =3D=3D 2 && mod_col =3D=3D 0) + is_aperture =3D 1; + + return is_aperture; +} + +void VL53LX_decode_row_col(uint8_t spad_number, uint8_t *prow, uint8_t *pc= ol) +{ + if (spad_number > 127) { + *prow =3D 8 + ((255-spad_number) & 0x07); + *pcol =3D (spad_number-128) >> 3; + } else { + *prow =3D spad_number & 0x07; + *pcol =3D (127-spad_number) >> 3; + } +} + +void VL53LX_decode_zone_size(uint8_t encoded_xy_size, uint8_t *pwidth, uin= t8_t *pheight) +{ + *pheight =3D encoded_xy_size >> 4; + *pwidth =3D encoded_xy_size & 0x0F; +} + +void VL53LX_decode_zone_limits(uint8_t encoded_xy_centre, uint8_t encoded_= xy_size, int16_t *px_ll, int16_t *py_ll, int16_t *px_ur, int16_t *py_ur) +{ + uint8_t x_centre =3D 0; + uint8_t y_centre =3D 0; + uint8_t width =3D 0; + uint8_t height =3D 0; + + VL53LX_decode_row_col(encoded_xy_centre, &y_centre, &x_centre); + VL53LX_decode_zone_size(encoded_xy_size, &width, &height); + + *px_ll =3D (int16_t)x_centre - ((int16_t)width + 1) / 2; + if (*px_ll < 0) + *px_ll =3D 0; + + *px_ur =3D *px_ll + (int16_t)width; + if (*px_ur > (VL53LX_SPAD_ARRAY_WIDTH-1)) + *px_ur =3D VL53LX_SPAD_ARRAY_WIDTH-1; + + *py_ll =3D (int16_t)y_centre - ((int16_t)height + 1) / 2; + if (*py_ll < 0) + *py_ll =3D 0; + + *py_ur =3D *py_ll + (int16_t)height; + if (*py_ur > (VL53LX_SPAD_ARRAY_HEIGHT-1)) + *py_ur =3D VL53LX_SPAD_ARRAY_HEIGHT-1; +} + +void VL53LX_calc_mm_effective_spads( + uint8_t encoded_mm_roi_centre, + uint8_t encoded_mm_roi_size, + uint8_t encoded_zone_centre, + uint8_t encoded_zone_size, + uint8_t *pgood_spads, + uint16_t aperture_attenuation, + uint16_t *pmm_inner_effective_spads, + uint16_t *pmm_outer_effective_spads) +{ + int16_t x =3D 0; + int16_t y =3D 0; + int16_t mm_x_ll =3D 0; + int16_t mm_y_ll =3D 0; + int16_t mm_x_ur =3D 0; + int16_t mm_y_ur =3D 0; + int16_t zone_x_ll =3D 0; + int16_t zone_y_ll =3D 0; + int16_t zone_x_ur =3D 0; + int16_t zone_y_ur =3D 0; + uint8_t spad_number =3D 0; + uint8_t byte_index =3D 0; + uint8_t bit_index =3D 0; + uint8_t bit_mask =3D 0; + + uint8_t is_aperture =3D 0; + uint16_t spad_attenuation =3D 0; + + VL53LX_decode_zone_limits(encoded_mm_roi_centre, encoded_mm_roi_size, &mm= _x_ll, &mm_y_ll, &mm_x_ur, &mm_y_ur); + VL53LX_decode_zone_limits(encoded_zone_centre, encoded_zone_size, &zone_x= _ll, &zone_y_ll, &zone_x_ur, &zone_y_ur); + + *pmm_inner_effective_spads =3D 0; + *pmm_outer_effective_spads =3D 0; + + for (y =3D zone_y_ll; y <=3D zone_y_ur; y++) { + for (x =3D zone_x_ll; x <=3D zone_x_ur; x++) { + VL53LX_encode_row_col((uint8_t)y, (uint8_t)x, &spad_number); + VL53LX_spad_number_to_byte_bit_index(spad_number, &byte_index, &bit_ind= ex, &bit_mask); + if ((pgood_spads[byte_index] & bit_mask) > 0) { + is_aperture =3D VL53LX_is_aperture_location((uint8_t)y, (uint8_t)x); + if (is_aperture > 0) + spad_attenuation =3D aperture_attenuation; + else + spad_attenuation =3D 0x0100; + if (x >=3D mm_x_ll && x <=3D mm_x_ur && y >=3D mm_y_ll && y <=3D mm_y_= ur) + *pmm_inner_effective_spads +=3D spad_attenuation; + else + *pmm_outer_effective_spads +=3D spad_attenuation; + } + } + } +} + +VL53LX_Error VL53LX_nvm_decode_fmt_range_results_data(uint16_t buf_size, u= int8_t *pbuffer, VL53LX_decoded_nvm_fmt_range_data_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + if (buf_size < VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES) + return VL53LX_ERROR_BUFFER_TOO_SMALL; + + pdata->result__actual_effective_rtn_spads =3D (uint16_t)VL53LX_i2c_decode= _uint16_t(2, pbuffer); + pdata->ref_spad_array__num_requested_ref_spads =3D *(pbuffer+2); + pdata->ref_spad_array__ref_location =3D *(pbuffer+3); + pdata->result__peak_signal_count_rate_rtn_mcps =3D (uint16_t)VL53LX_i2c_d= ecode_uint16_t(2, pbuffer + 4); + pdata->result__ambient_count_rate_rtn_mcps =3D (uint16_t)VL53LX_i2c_decod= e_uint16_t(2, pbuffer + 6); + pdata->result__peak_signal_count_rate_ref_mcps =3D (uint16_t)VL53LX_i2c_d= ecode_uint16_t(2, pbuffer + 8); + pdata->result__ambient_count_rate_ref_mcps =3D (uint16_t)VL53LX_i2c_decod= e_uint16_t(2, pbuffer + 10); + pdata->measured_distance_mm =3D (uint16_t)VL53LX_i2c_decode_uint16_t(2, p= buffer + 12); + pdata->measured_distance_stdev_mm =3D (uint16_t)VL53LX_i2c_decode_uint16_= t(2, pbuffer + 14); + + return status; +} + +VL53LX_Error VL53LX_read_nvm_fmt_range_results_data(VL53LX_DEV Dev, uint16= _t range_results_select, VL53LX_decoded_nvm_fmt_range_data_t *prange_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t nvm_data[VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES]; + + status =3D VL53LX_read_nvm_raw_data(Dev, (uint8_t)(range_results_select >= > 2), (uint8_t)(VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES >> 2), +nvm_data); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_nvm_decode_fmt_range_results_data(VL53LX_NVM__FMT__RAN= GE_RESULTS__SIZE_BYTES, nvm_data, prange_data); + + return status; +} + +VL53LX_Error VL53LX_get_mode_mitigation_roi(VL53LX_DEV Dev, VL53LX_user_zo= ne_t *pmm_roi) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t x =3D 0; + uint8_t y =3D 0; + uint8_t xy_size =3D 0; + + VL53LX_decode_row_col(pdev->nvm_copy_data.roi_config__mode_roi_centre_spa= d, &y, &x); + + pmm_roi->x_centre =3D x; + pmm_roi->y_centre =3D y; + + xy_size =3D pdev->nvm_copy_data.roi_config__mode_roi_xy_size; + + pmm_roi->height =3D xy_size >> 4; + pmm_roi->width =3D xy_size & 0x0F; + + return status; +} + +VL53LX_Error VL53LX_read_p2p_data(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_hist_post_process_config_t *pHP =3D &(pdev->histpostprocess); + VL53LX_customer_nvm_managed_t *pN =3D &(pdev->customer); + VL53LX_additional_offset_cal_data_t *pCD =3D &(pdev->add_off_cal_data); + VL53LX_decoded_nvm_fmt_range_data_t fmt_rrd; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_get_static_nvm_managed(Dev, &(pdev->stat_nvm)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_get_customer_nvm_managed(Dev, &(pdev->customer)); + + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_get_nvm_copy_data(Dev, &(pdev->nvm_copy_data)); + + if (status =3D=3D VL53LX_ERROR_NONE) + VL53LX_copy_rtn_good_spads_to_buffer(&(pdev->nvm_copy_data), &(pdev->rt= n_good_spads[0])); + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + pHP->algo__crosstalk_compensation_plane_offset_kcps =3D + pN->algo__crosstalk_compensation_plane_offset_kcps; + pHP->algo__crosstalk_compensation_x_plane_gradient_kcps =3D + pN->algo__crosstalk_compensation_x_plane_gradient_kcps; + pHP->algo__crosstalk_compensation_y_plane_gradient_kcps =3D + pN->algo__crosstalk_compensation_y_plane_gradient_kcps; + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_read_nvm_optical_centre(Dev, &(pdev->optical_centre)); + + + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_read_nvm_cal_peak_rate_map(Dev, &(pdev->cal_peak_rate_= map)); + + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_read_nvm_additional_offset_cal_data(Dev, &(pdev->add_o= ff_cal_data)); + + if (pCD->result__mm_inner_peak_signal_count_rtn_mcps =3D=3D 0 && pCD->re= sult__mm_outer_peak_signal_count_rtn_mcps =3D=3D 0) { + pCD->result__mm_inner_peak_signal_count_rtn_mcps =3D 0x0080; + pCD->result__mm_outer_peak_signal_count_rtn_mcps =3D 0x0180; + + VL53LX_calc_mm_effective_spads(pdev->nvm_copy_data.roi_config__mode_roi= _centre_spad, pdev->nvm_copy_data.roi_config__mode_roi_xy_size, 0xC7, 0xFF,= &(pdev->rtn_good_spads[0]), VL53LX_RTN_SPAD_APERTURE_TRANSMISSION, &(pCD->= result__mm_inner_actual_effective_spads), &(pCD->result__mm_outer_actual_ef= fective_spads)); + } + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + + status =3D VL53LX_read_nvm_fmt_range_results_data(Dev, VL53LX_NVM__FMT__= RANGE_RESULTS__140MM_DARK, &fmt_rrd); + if (status =3D=3D VL53LX_ERROR_NONE) { + pdev->fmt_dmax_cal.ref__actual_effective_spads =3D fmt_rrd.result__actu= al_effective_rtn_spads; + pdev->fmt_dmax_cal.ref__peak_signal_count_rate_mcps =3D fmt_rrd.result_= _peak_signal_count_rate_rtn_mcps; + pdev->fmt_dmax_cal.ref__distance_mm =3D fmt_rrd.measured_distance_mm; + + if (pdev->cal_peak_rate_map.cal_reflectance_pc !=3D 0) { + pdev->fmt_dmax_cal.ref_reflectance_pc =3D pdev->cal_peak_rate_map.cal_= reflectance_pc; + } else { + pdev->fmt_dmax_cal.ref_reflectance_pc =3D 0x0014; + } + pdev->fmt_dmax_cal.coverglass_transmission =3D 0x0100; + } + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_RdWord(Dev, VL53LX_RESULT__OSC_CALIBRATE_VAL, &(pdev->= dbg_results.result__osc_calibrate_val)); + + if (pdev->stat_nvm.osc_measured__fast_osc__frequency < 0x1000) { + pdev->stat_nvm.osc_measured__fast_osc__frequency =3D 0xBCCC; + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_get_mode_mitigation_roi(Dev, &(pdev->mm_roi)); + + if (pdev->optical_centre.x_centre =3D=3D 0 && pdev->optical_centre.y_cent= re =3D=3D 0) { + pdev->optical_centre.x_centre =3D pdev->mm_roi.x_centre << 4; + pdev->optical_centre.y_centre =3D pdev->mm_roi.y_centre << 4; + } + return status; +} + +VL53LX_Error VL53LX_init_refspadchar_config_struct(VL53LX_refspadchar_conf= ig_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pdata->device_test_mode =3D VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE= _TEST_MODE_DEFAULT; + pdata->VL53LX_p_005 =3D VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_= PERIOD_DEFAULT; + pdata->timeout_us =3D VL53LX_TUNINGPARM_REFSPADCHAR_PHASEC= AL_TIMEOUT_US_DEFAULT; + pdata->target_count_rate_mcps =3D VL53LX_TUNINGPARM_REFSPADCHAR_TARGET= _COUNT_RATE_MCPS_DEFAULT; + pdata->min_count_rate_limit_mcps =3D VL53LX_TUNINGPARM_REFSPADCHAR_MIN_CO= UNTRATE_LIMIT_MCPS_DEFAULT; + pdata->max_count_rate_limit_mcps =3D VL53LX_TUNINGPARM_REFSPADCHAR_MAX_CO= UNTRATE_LIMIT_MCPS_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX_init_ssc_config_struct(VL53LX_ssc_config_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pdata->array_select =3D VL53LX_DEVICESSCARRAY_RTN; + pdata->VL53LX_p_005 =3D VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD_DEFAULT; + pdata->vcsel_start =3D VL53LX_TUNINGPARM_SPADMAP_VCSEL_START_DEFAULT; + pdata->vcsel_width =3D 0x02; + pdata->timeout_us =3D 36000; + pdata->rate_limit_mcps =3D VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS_DEFA= ULT; + + return status; +} + +VL53LX_Error VL53LX_init_xtalk_config_struct(VL53LX_customer_nvm_managed_t= *pnvm, VL53LX_xtalk_config_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pdata->algo__crosstalk_compensation_plane_offset_kcps =3D pnvm->algo= __crosstalk_compensation_plane_offset_kcps; + pdata->algo__crosstalk_compensation_x_plane_gradient_kcps =3D pnvm->algo= __crosstalk_compensation_x_plane_gradient_kcps; + pdata->algo__crosstalk_compensation_y_plane_gradient_kcps =3D pnvm->algo= __crosstalk_compensation_y_plane_gradient_kcps; + + pdata->nvm_default__crosstalk_compensation_plane_offset_kcps =3D (ui= nt32_t)pnvm->algo__crosstalk_compensation_plane_offset_kcps; + pdata->nvm_default__crosstalk_compensation_x_plane_gradient_kcps =3D pnv= m->algo__crosstalk_compensation_x_plane_gradient_kcps; + pdata->nvm_default__crosstalk_compensation_y_plane_gradient_kcps =3D pnv= m->algo__crosstalk_compensation_y_plane_gradient_kcps; + + pdata->histogram_mode_crosstalk_margin_kcps =3D VL53LX_TUN= INGPARM_HIST_XTALK_MARGIN_KCPS_DEFAULT; + pdata->lite_mode_crosstalk_margin_kcps =3D VL53LX_TUN= INGPARM_LITE_XTALK_MARGIN_KCPS_DEFAULT; + + pdata->crosstalk_range_ignore_threshold_mult =3D VL53LX_TUNINGPARM_LITE_R= IT_MULT_DEFAULT; + + if ((pdata->algo__crosstalk_compensation_plane_offset_kcps =3D=3D 0x00) &= & (pdata->algo__crosstalk_compensation_x_plane_gradient_kcps =3D=3D 0x00) &= & (pdata->algo__crosstalk_compensation_y_plane_gradient_kcps =3D=3D 0x00)) + pdata->global_crosstalk_compensation_enable =3D 0x00; + else + pdata->global_crosstalk_compensation_enable =3D 0x01; + + if ((status =3D=3D VL53LX_ERROR_NONE) && (pdata->global_crosstalk_compens= ation_enable =3D=3D 0x01)) { + pdata->crosstalk_range_ignore_threshold_rate_mcps =3D VL53LX_calc_range_= ignore_threshold(pdata->algo__crosstalk_compensation_plane_offset_kcps, pda= ta->algo__crosstalk_compensation_x_plane_gradient_kcps, pdata->algo__crosst= alk_compensation_y_plane_gradient_kcps, pdata->crosstalk_range_ignore_thres= hold_mult); + } else { + pdata->crosstalk_range_ignore_threshold_rate_mcps =3D 0; + } + + pdata->algo__crosstalk_detect_min_valid_range_mm =3D VL53LX_TUNINGPARM_X= TALK_DETECT_MIN_VALID_RANGE_MM_DEFAULT; + pdata->algo__crosstalk_detect_max_valid_range_mm =3D VL53LX_TUNINGPARM_X= TALK_DETECT_MAX_VALID_RANGE_MM_DEFAULT; + pdata->algo__crosstalk_detect_max_valid_rate_kcps =3D VL53LX_TUNINGPARM_X= TALK_DETECT_MAX_VALID_RATE_KCPS_DEFAULT; + pdata->algo__crosstalk_detect_max_sigma_mm =3D VL53LX_TUNINGPARM_X= TALK_DETECT_MAX_SIGMA_MM_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX_init_xtalk_extract_config_struct(VL53LX_xtalkextract_c= onfig_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pdata->dss_config__target_total_rate_mcps =3D VL53LX_TUNINGPARM_= XTALK_EXTRACT_DSS_RATE_MCPS_DEFAULT; + pdata->mm_config_timeout_us =3D VL53LX_TUNINGPARM_= XTALK_EXTRACT_DSS_TIMEOUT_US_DEFAULT; + pdata->num_of_samples =3D VL53LX_TUNINGPARM_= XTALK_EXTRACT_NUM_OF_SAMPLES_DEFAULT; + pdata->phasecal_config_timeout_us =3D VL53LX_TUNINGPARM_= XTALK_EXTRACT_PHASECAL_TIMEOUT_US_DEFAULT; + pdata->range_config_timeout_us =3D VL53LX_TUNINGPARM_= XTALK_EXTRACT_BIN_TIMEOUT_US_DEFAULT; + pdata->algo__crosstalk_extract_min_valid_range_mm =3D VL53LX_TUNINGPARM_= XTALK_EXTRACT_MIN_FILTER_THRESH_MM_DEFAULT; + pdata->algo__crosstalk_extract_max_valid_range_mm =3D VL53LX_TUNINGPARM_= XTALK_EXTRACT_MAX_FILTER_THRESH_MM_DEFAULT; + pdata->algo__crosstalk_extract_max_valid_rate_kcps =3D VL53LX_TUNINGPARM_= XTALK_EXTRACT_MAX_VALID_RATE_KCPS_DEFAULT; + pdata->algo__crosstalk_extract_max_sigma_mm =3D VL53LX_TUNINGPARM_= XTALK_EXTRACT_SIGMA_THRESHOLD_MM_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX_init_offset_cal_config_struct(VL53LX_offsetcal_config_= t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pdata->dss_config__target_total_rate_mcps =3D VL53LX_TUNINGPARM_= OFFSET_CAL_DSS_RATE_MCPS_DEFAULT; + pdata->phasecal_config_timeout_us =3D VL53LX_TUNINGPARM_= OFFSET_CAL_PHASECAL_TIMEOUT_US_DEFAULT; + pdata->range_config_timeout_us =3D VL53LX_TUNINGPARM_= OFFSET_CAL_RANGE_TIMEOUT_US_DEFAULT; + pdata->mm_config_timeout_us =3D VL53LX_TUNINGPARM_= OFFSET_CAL_MM_TIMEOUT_US_DEFAULT; + pdata->pre_num_of_samples =3D VL53LX_TUNINGPARM_= OFFSET_CAL_PRE_SAMPLES_DEFAULT; + pdata->mm1_num_of_samples =3D VL53LX_TUNINGPARM_= OFFSET_CAL_MM1_SAMPLES_DEFAULT; + pdata->mm2_num_of_samples =3D VL53LX_TUNINGPARM_= OFFSET_CAL_MM2_SAMPLES_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX_init_zone_cal_config_struct(VL53LX_zonecal_config_t *p= data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pdata->dss_config__target_total_rate_mcps =3D VL53LX_TUNINGPARM_= ZONE_CAL_DSS_RATE_MCPS_DEFAULT; + pdata->phasecal_config_timeout_us =3D VL53LX_TUNINGPARM_= ZONE_CAL_PHASECAL_TIMEOUT_US_DEFAULT; + pdata->range_config_timeout_us =3D VL53LX_TUNINGPARM_= ZONE_CAL_RANGE_TIMEOUT_US_DEFAULT; + pdata->mm_config_timeout_us =3D VL53LX_TUNINGPARM_= ZONE_CAL_DSS_TIMEOUT_US_DEFAULT; + pdata->phasecal_num_of_samples =3D VL53LX_TUNINGPARM_= ZONE_CAL_PHASECAL_NUM_SAMPLES_DEFAULT; + pdata->zone_num_of_samples =3D VL53LX_TUNINGPARM_= ZONE_CAL_ZONE_NUM_SAMPLES_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX_init_hist_post_process_config_struct(uint8_t xtalk_com= pensation_enable, VL53LX_hist_post_process_config_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pdata->hist_algo_select =3D VL53LX_TUNINGPARM_HIST_ALGO_SELECT_DEFAULT; + pdata->hist_target_order =3D VL53LX_TUNINGPARM_HIST_TARGET_ORDER_DEFAULT; + + pdata->filter_woi0 =3D VL53LX_TUNINGPARM_HIST_FILTER_WO= I_0_DEFAULT; + pdata->filter_woi1 =3D VL53LX_TUNINGPARM_HIST_FILTER_WO= I_1_DEFAULT; + + pdata->hist_amb_est_method =3D VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD_DEFA= ULT; + + pdata->ambient_thresh_sigma0 =3D VL53LX_TUNINGPARM_HIST_AMB_THRES= H_SIGMA_0_DEFAULT; + pdata->ambient_thresh_sigma1 =3D VL53LX_TUNINGPARM_HIST_AMB_THRES= H_SIGMA_1_DEFAULT; + + pdata->ambient_thresh_events_scaler =3D VL53LX_TUNINGPARM_HIST_AMB_EV= ENTS_SCALER_DEFAULT; + + pdata->min_ambient_thresh_events =3D VL53LX_TUNINGPARM_HIST_MIN_AMB_T= HRESH_EVENTS_DEFAULT; + + pdata->noise_threshold =3D VL53LX_TUNINGPARM_HIST_NOISE_THR= ESHOLD_DEFAULT; + + pdata->signal_total_events_limit =3D VL53LX_TUNINGPARM_HIST_SIGNAL_TO= TAL_EVENTS_LIMIT_DEFAULT; + pdata->sigma_estimator__sigma_ref_mm =3D VL53LX_TUNINGPARM_HIST_SIGMA_EST= _REF_MM_DEFAULT; + + pdata->sigma_thresh =3D VL53LX_TUNINGPARM_HIST_SIGMA_THR= ESH_MM_DEFAULT; + pdata->range_offset_mm =3D 0; + pdata->gain_factor =3D VL53LX_TUNINGPARM_HIST_GAIN_FACTOR_= DEFAULT; + + pdata->valid_phase_low =3D 0x08; + pdata->valid_phase_high =3D 0x88; + + pdata->algo__consistency_check__phase_tolerance =3D VL53LX_TUNINGPARM_CON= SISTENCY_HIST_PHASE_TOLERANCE_DEFAULT; + pdata->algo__consistency_check__event_sigma =3D VL53LX_TUNINGPARM_CONSIST= ENCY_HIST_EVENT_SIGMA_DEFAULT; + pdata->algo__consistency_check__event_min_spad_count =3D VL53LX_TUNINGPAR= M_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT_DEFAULT; + pdata->algo__consistency_check__min_max_tolerance =3D VL53LX_TUNINGPARM_C= ONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM_DEFAULT; + pdata->algo__crosstalk_compensation_enable =3D xtalk_compensation_enable; + pdata->algo__crosstalk_detect_min_valid_range_mm =3D VL53LX_TUNINGPARM_X= TALK_DETECT_MIN_VALID_RANGE_MM_DEFAULT; + pdata->algo__crosstalk_detect_max_valid_range_mm =3D VL53LX_TUNINGPARM_X= TALK_DETECT_MAX_VALID_RANGE_MM_DEFAULT; + pdata->algo__crosstalk_detect_max_valid_rate_kcps =3D VL53LX_TUNINGPARM_X= TALK_DETECT_MAX_VALID_RATE_KCPS_DEFAULT; + pdata->algo__crosstalk_detect_max_sigma_mm =3D VL53LX_TUNINGPARM_X= TALK_DETECT_MAX_SIGMA_MM_DEFAULT; + + pdata->algo__crosstalk_detect_event_sigma =3D VL53LX_TUNINGPARM_XTA= LK_DETECT_EVENT_SIGMA_DEFAULT; + + pdata->algo__crosstalk_detect_min_max_tolerance =3D VL53LX_TUNINGPARM_X= TALK_DETECT_MIN_MAX_TOLERANCE_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX_init_hist_gen3_dmax_config_struct(VL53LX_hist_gen3_dma= x_config_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pdata->dss_config__target_total_rate_mcps =3D 0x1400; + pdata->dss_config__aperture_attenuation =3D 0x38; + + pdata->signal_thresh_sigma =3D VL53LX_TUNINGPARM_DMAX_CFG= _SIGNAL_THRESH_SIGMA_DEFAULT; + pdata->ambient_thresh_sigma =3D 0x70; + pdata->min_ambient_thresh_events =3D 16; + pdata->signal_total_events_limit =3D 100; + pdata->max_effective_spads =3D 0xFFFF; + + pdata->target_reflectance_for_dmax_calc[0] =3D VL53LX_TUNINGPARM_DMAX_CFG= _REFLECTANCE_ARRAY_0_DEFAULT; + pdata->target_reflectance_for_dmax_calc[1] =3D VL53LX_TUNINGPARM_DMAX_CFG= _REFLECTANCE_ARRAY_1_DEFAULT; + pdata->target_reflectance_for_dmax_calc[2] =3D VL53LX_TUNINGPARM_DMAX_CFG= _REFLECTANCE_ARRAY_2_DEFAULT; + pdata->target_reflectance_for_dmax_calc[3] =3D VL53LX_TUNINGPARM_DMAX_CFG= _REFLECTANCE_ARRAY_3_DEFAULT; + pdata->target_reflectance_for_dmax_calc[4] =3D VL53LX_TUNINGPARM_DMAX_CFG= _REFLECTANCE_ARRAY_4_DEFAULT; + + return status; +} + +VL53LX_Error VL53LX_init_tuning_parm_storage_struct(VL53LX_tuning_parm_sto= rage_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pdata->tp_tuning_parm_version =3D VL53LX_TUNINGPARM_VERSION_= DEFAULT; + pdata->tp_tuning_parm_key_table_version =3D VL53LX_TUNINGPARM_KEY_TABL= E_VERSION_DEFAULT; + pdata->tp_tuning_parm_lld_version =3D VL53LX_TUNINGPARM_LLD_VERS= ION_DEFAULT; + pdata->tp_init_phase_rtn_lite_long =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_RTN_LITE_LONG_RANGE_DEFAULT; + pdata->tp_init_phase_rtn_lite_med =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_RTN_LITE_MED_RANGE_DEFAULT; + pdata->tp_init_phase_rtn_lite_short =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_RTN_LITE_SHORT_RANGE_DEFAULT; + pdata->tp_init_phase_ref_lite_long =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_REF_LITE_LONG_RANGE_DEFAULT; + pdata->tp_init_phase_ref_lite_med =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_REF_LITE_MED_RANGE_DEFAULT; + pdata->tp_init_phase_ref_lite_short =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_REF_LITE_SHORT_RANGE_DEFAULT; + pdata->tp_init_phase_rtn_hist_long =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_RTN_HISTO_LONG_RANGE_DEFAULT; + pdata->tp_init_phase_rtn_hist_med =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_RTN_HISTO_MED_RANGE_DEFAULT; + pdata->tp_init_phase_rtn_hist_short =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_RTN_HISTO_SHORT_RANGE_DEFAULT; + pdata->tp_init_phase_ref_hist_long =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_REF_HISTO_LONG_RANGE_DEFAULT; + pdata->tp_init_phase_ref_hist_med =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_REF_HISTO_MED_RANGE_DEFAULT; + pdata->tp_init_phase_ref_hist_short =3D VL53LX_TUNINGPARM_INITIAL_= PHASE_REF_HISTO_SHORT_RANGE_DEFAULT; + pdata->tp_consistency_lite_phase_tolerance =3D VL53LX_TUNINGPARM_CONSISTE= NCY_LITE_PHASE_TOLERANCE_DEFAULT; + pdata->tp_phasecal_target =3D VL53LX_TUNINGPARM_PHASECAL= _TARGET_DEFAULT; + pdata->tp_cal_repeat_rate =3D VL53LX_TUNINGPARM_LITE_CAL= _REPEAT_RATE_DEFAULT; + pdata->tp_lite_min_clip =3D VL53LX_TUNINGPARM_LITE_MIN= _CLIP_MM_DEFAULT; + pdata->tp_lite_long_sigma_thresh_mm =3D VL53LX_TUNINGPARM_LITE_LON= G_SIGMA_THRESH_MM_DEFAULT; + pdata->tp_lite_med_sigma_thresh_mm =3D VL53LX_TUNINGPARM_LITE_MED= _SIGMA_THRESH_MM_DEFAULT; + pdata->tp_lite_short_sigma_thresh_mm =3D VL53LX_TUNINGPARM_LITE_SHO= RT_SIGMA_THRESH_MM_DEFAULT; + pdata->tp_lite_long_min_count_rate_rtn_mcps =3D VL53LX_TUNINGPARM_LITE_L= ONG_MIN_COUNT_RATE_RTN_MCPS_DEFAULT; + pdata->tp_lite_med_min_count_rate_rtn_mcps =3D VL53LX_TUNINGPARM_LITE_M= ED_MIN_COUNT_RATE_RTN_MCPS_DEFAULT; + pdata->tp_lite_short_min_count_rate_rtn_mcps =3D VL53LX_TUNINGPARM_LITE_S= HORT_MIN_COUNT_RATE_RTN_MCPS_DEFAULT; + pdata->tp_lite_sigma_est_pulse_width_ns =3D VL53LX_TUNINGPARM_LITE_S= IGMA_EST_PULSE_WIDTH_DEFAULT; + pdata->tp_lite_sigma_est_amb_width_ns =3D VL53LX_TUNINGPARM_LITE_S= IGMA_EST_AMB_WIDTH_NS_DEFAULT; + pdata->tp_lite_sigma_ref_mm =3D VL53LX_TUNINGPARM_LITE_S= IGMA_REF_MM_DEFAULT; + pdata->tp_lite_seed_cfg =3D VL53LX_TUNINGPARM_LITE_S= EED_CONFIG_DEFAULT; + pdata->tp_timed_seed_cfg =3D VL53LX_TUNINGPARM_TIMED_= SEED_CONFIG_DEFAULT; + pdata->tp_lite_quantifier =3D VL53LX_TUNINGPARM_LITE_Q= UANTIFIER_DEFAULT; + pdata->tp_lite_first_order_select =3D VL53LX_TUNINGPARM_LITE_F= IRST_ORDER_SELECT_DEFAULT; + pdata->tp_uwr_enable =3D VL53LX_TUNINGPARM_UWR_ENABLE_DEFAULT; + pdata->tp_uwr_med_z_1_min =3D VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MIN_DEF= AULT; + pdata->tp_uwr_med_z_1_max =3D VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MAX_DEF= AULT; + pdata->tp_uwr_med_z_2_min =3D VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MIN_DEF= AULT; + pdata->tp_uwr_med_z_2_max =3D VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MAX_DEF= AULT; + pdata->tp_uwr_med_z_3_min =3D VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MIN_DEF= AULT; + pdata->tp_uwr_med_z_3_max =3D VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MAX_DEF= AULT; + pdata->tp_uwr_med_z_4_min =3D VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MIN_DEF= AULT; + pdata->tp_uwr_med_z_4_max =3D VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MAX_DEF= AULT; + pdata->tp_uwr_med_z_5_min =3D VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MIN_DEF= AULT; + pdata->tp_uwr_med_z_5_max =3D VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MAX_DEF= AULT; + pdata->tp_uwr_med_corr_z_1_rangea =3D VL53LX_TUNINGPARM_UWR_MEDIUM_CORREC= TION_ZONE_1_RANGEA_DEFAULT; + pdata->tp_uwr_med_corr_z_1_rangeb =3D VL53LX_TUNINGPARM_UWR_MEDIUM_CORREC= TION_ZONE_1_RANGEB_DEFAULT; + pdata->tp_uwr_med_corr_z_2_rangea =3D VL53LX_TUNINGPARM_UWR_MEDIUM_CORREC= TION_ZONE_2_RANGEA_DEFAULT; + pdata->tp_uwr_med_corr_z_2_rangeb =3D VL53LX_TUNINGPARM_UWR_MEDIUM_CORREC= TION_ZONE_2_RANGEB_DEFAULT; + pdata->tp_uwr_med_corr_z_3_rangea =3D VL53LX_TUNINGPARM_UWR_MEDIUM_CORREC= TION_ZONE_3_RANGEA_DEFAULT; + pdata->tp_uwr_med_corr_z_3_rangeb =3D VL53LX_TUNINGPARM_UWR_MEDIUM_CORREC= TION_ZONE_3_RANGEB_DEFAULT; + pdata->tp_uwr_med_corr_z_4_rangea =3D VL53LX_TUNINGPARM_UWR_MEDIUM_CORREC= TION_ZONE_4_RANGEA_DEFAULT; + pdata->tp_uwr_med_corr_z_4_rangeb =3D VL53LX_TUNINGPARM_UWR_MEDIUM_CORREC= TION_ZONE_4_RANGEB_DEFAULT; + pdata->tp_uwr_med_corr_z_5_rangea =3D VL53LX_TUNINGPARM_UWR_MEDIUM_CORREC= TION_ZONE_5_RANGEA_DEFAULT; + pdata->tp_uwr_med_corr_z_5_rangeb =3D VL53LX_TUNINGPARM_UWR_MEDIUM_CORREC= TION_ZONE_5_RANGEB_DEFAULT; + pdata->tp_uwr_lng_z_1_min =3D VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MIN_DEFAU= LT; + pdata->tp_uwr_lng_z_1_max =3D VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MAX_DEFAU= LT; + pdata->tp_uwr_lng_z_2_min =3D VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MIN_DEFAU= LT; + pdata->tp_uwr_lng_z_2_max =3D VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MAX_DEFAU= LT; + pdata->tp_uwr_lng_z_3_min =3D VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MIN_DEFAU= LT; + pdata->tp_uwr_lng_z_3_max =3D VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MAX_DEFAU= LT; + pdata->tp_uwr_lng_z_4_min =3D VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MIN_DEFAU= LT; + pdata->tp_uwr_lng_z_4_max =3D VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MAX_DEFAU= LT; + pdata->tp_uwr_lng_z_5_min =3D VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MIN_DEFAU= LT; + pdata->tp_uwr_lng_z_5_max =3D VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MAX_DEFAU= LT; + pdata->tp_uwr_lng_corr_z_1_rangea =3D VL53LX_TUNINGPARM_UWR_LONG_CORRECTI= ON_ZONE_1_RANGEA_DEFAULT; + pdata->tp_uwr_lng_corr_z_1_rangeb =3D VL53LX_TUNINGPARM_UWR_LONG_CORRECTI= ON_ZONE_1_RANGEB_DEFAULT; + pdata->tp_uwr_lng_corr_z_2_rangea =3D VL53LX_TUNINGPARM_UWR_LONG_CORRECTI= ON_ZONE_2_RANGEA_DEFAULT; + pdata->tp_uwr_lng_corr_z_2_rangeb =3D VL53LX_TUNINGPARM_UWR_LONG_CORRECTI= ON_ZONE_2_RANGEB_DEFAULT; + pdata->tp_uwr_lng_corr_z_3_rangea =3D VL53LX_TUNINGPARM_UWR_LONG_CORRECTI= ON_ZONE_3_RANGEA_DEFAULT; + pdata->tp_uwr_lng_corr_z_3_rangeb =3D VL53LX_TUNINGPARM_UWR_LONG_CORRECTI= ON_ZONE_3_RANGEB_DEFAULT; + pdata->tp_uwr_lng_corr_z_4_rangea =3D VL53LX_TUNINGPARM_UWR_LONG_CORRECTI= ON_ZONE_4_RANGEA_DEFAULT; + pdata->tp_uwr_lng_corr_z_4_rangeb =3D VL53LX_TUNINGPARM_UWR_LONG_CORRECTI= ON_ZONE_4_RANGEB_DEFAULT; + pdata->tp_uwr_lng_corr_z_5_rangea =3D VL53LX_TUNINGPARM_UWR_LONG_CORRECTI= ON_ZONE_5_RANGEA_DEFAULT; + pdata->tp_uwr_lng_corr_z_5_rangeb =3D VL53LX_TUNINGPARM_UWR_LONG_CORRECTI= ON_ZONE_5_RANGEB_DEFAULT; + + pdata->tp_dss_target_lite_mcps =3D VL53LX_TUNINGPARM_LITE_D= SS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT; + pdata->tp_dss_target_histo_mcps =3D VL53LX_TUNINGPARM_RANGIN= G_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT; + pdata->tp_dss_target_histo_mz_mcps =3D VL53LX_TUNINGPARM_MZ_DSS= _CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT; + pdata->tp_dss_target_timed_mcps =3D VL53LX_TUNINGPARM_TIMED_= DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT; + pdata->tp_phasecal_timeout_lite_us =3D VL53LX_TUNINGPARM_LITE_P= HASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_hist_long_us =3D VL53LX_TUNINGPARM_RANGIN= G_LONG_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_hist_med_us =3D VL53LX_TUNINGPARM_RANGIN= G_MED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_hist_short_us =3D VL53LX_TUNINGPARM_RANGIN= G_SHORT_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_mz_long_us =3D VL53LX_TUNINGPARM_MZ_LON= G_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_mz_med_us =3D VL53LX_TUNINGPARM_MZ_MED= _PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_mz_short_us =3D VL53LX_TUNINGPARM_MZ_SHO= RT_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_phasecal_timeout_timed_us =3D VL53LX_TUNINGPARM_TIMED_= PHASECAL_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_mm_timeout_lite_us =3D VL53LX_TUNINGPARM_LITE_M= M_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_mm_timeout_histo_us =3D VL53LX_TUNINGPARM_RANGIN= G_MM_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_mm_timeout_mz_us =3D VL53LX_TUNINGPARM_MZ_MM_= CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_mm_timeout_timed_us =3D VL53LX_TUNINGPARM_TIMED_= MM_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_range_timeout_lite_us =3D VL53LX_TUNINGPARM_LITE_R= ANGE_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_range_timeout_histo_us =3D VL53LX_TUNINGPARM_RANGIN= G_RANGE_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_range_timeout_mz_us =3D VL53LX_TUNINGPARM_MZ_RAN= GE_CONFIG_TIMEOUT_US_DEFAULT; + pdata->tp_range_timeout_timed_us =3D VL53LX_TUNINGPARM_TIMED_= RANGE_CONFIG_TIMEOUT_US_DEFAULT; + + pdata->tp_mm_timeout_lpa_us =3D VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_= TIMEOUT_US_DEFAULT; + pdata->tp_range_timeout_lpa_us =3D VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_C= ONFIG_TIMEOUT_US_DEFAULT; + + pdata->tp_dss_target_very_short_mcps =3D VL53LX_TUNINGPARM_VERY_SHORT_DSS= _RATE_MCPS_DEFAULT; + + pdata->tp_phasecal_patch_power =3D VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER= _DEFAULT; + + pdata->tp_hist_merge =3D VL53LX_TUNINGPARM_HIST_MERGE_DEFAULT; + + pdata->tp_reset_merge_threshold =3D VL53LX_TUNINGPARM_RESET_MERGE_THRESHO= LD_DEFAULT; + + pdata->tp_hist_merge_max_size =3D VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE_D= EFAULT; + + return status; +} + +VL53LX_Error VL53LX_preset_mode_histogram_short_range( + VL53LX_hist_post_process_config_t *phistpostprocess, + VL53LX_static_config_t *pstatic, + VL53LX_histogram_config_t *phistogram, + VL53LX_general_config_t *pgeneral, + VL53LX_timing_config_t *ptiming, + VL53LX_dynamic_config_t *pdynamic, + VL53LX_system_control_t *psystem, + VL53LX_tuning_parm_storage_t *ptuning_parms, + VL53LX_zone_config_t *pzone_cfg) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + status =3D VL53LX_preset_mode_histogram_ranging(phistpostprocess, pstatic= , phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cf= g); + if (status =3D=3D VL53LX_ERROR_NONE) { + VL53LX_init_histogram_config_structure(7, 7, 0, 1, 1, 1, 0, 1, 1, 1, 2, = 2, phistogram); + VL53LX_init_histogram_multizone_config_structure(7, 7, 0, 1, 1, 1, 0, 1,= 1, 1, 2, 2, &(pzone_cfg->multizone_hist_cfg)); + VL53LX_copy_hist_cfg_to_static_cfg(phistogram, pstatic, pgeneral, ptimin= g, pdynamic); + + ptiming->range_config__vcsel_period_a =3D 0x03; + ptiming->range_config__vcsel_period_b =3D 0x05; + + ptiming->mm_config__timeout_macrop_a_hi =3D 0x00; + ptiming->mm_config__timeout_macrop_a_lo =3D 0x52; + ptiming->mm_config__timeout_macrop_b_hi =3D 0x00; + ptiming->mm_config__timeout_macrop_b_lo =3D 0x37; + + ptiming->range_config__timeout_macrop_a_hi =3D 0x00; + ptiming->range_config__timeout_macrop_a_lo =3D 0x66; + ptiming->range_config__timeout_macrop_b_hi =3D 0x00; + ptiming->range_config__timeout_macrop_b_lo =3D 0x44; + + pgeneral->cal_config__vcsel_start =3D 0x03; + + pgeneral->phasecal_config__timeout_macrop =3D 0xF5; + + pdynamic->sd_config__woi_sd0 =3D 0x03; + pdynamic->sd_config__woi_sd1 =3D 0x05; + pdynamic->sd_config__initial_phase_sd0 =3D ptuning_parms->tp_= init_phase_rtn_hist_short; + pdynamic->sd_config__initial_phase_sd1 =3D ptuning_parms->tp_= init_phase_ref_hist_short; + + phistpostprocess->valid_phase_low =3D 0x08; + phistpostprocess->valid_phase_high =3D 0x28; + + pdynamic->system__sequence_config =3D VL53LX_SEQUENCE_VHV_EN | VL53LX_SE= QUENCE_PHASECAL_EN | VL53LX_SEQUENCE_DSS1_EN | VL53LX_SEQUENCE_DSS2_EN | VL= 53LX_SEQUENCE_MM1_EN | VL53LX_SEQUENCE_RANGE_EN; + + psystem->system__mode_start =3D VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | V= L53LX_DEVICEREADOUTMODE_DUAL_SD | VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + } + return status; +} + +void VL53LX_init_histogram_bin_data_struct(int32_t bin_value, uint16_t VL5= 3LX_p_021, VL53LX_histogram_bin_data_t *pdata) +{ + uint16_t i =3D 0; + + pdata->cfg_device_state =3D VL53LX_DEVICESTATE_SW_STANDBY; + pdata->rd_device_state =3D VL53LX_DEVICESTATE_SW_STANDBY; + pdata->zone_id =3D 0; + pdata->time_stamp =3D 0; + pdata->VL53LX_p_019 =3D 0; + pdata->VL53LX_p_020 =3D VL53LX_HISTOGRAM_BUFFER_SIZE; + pdata->VL53LX_p_021 =3D (uint8_t)VL53LX_p_021; + pdata->number_of_ambient_bins =3D 0; + pdata->result__interrupt_status =3D 0; + pdata->result__range_status =3D 0; + pdata->result__report_status =3D 0; + pdata->result__stream_count =3D 0; + pdata->result__dss_actual_effective_spads =3D 0; + pdata->phasecal_result__reference_phase =3D 0; + pdata->phasecal_result__vcsel_start =3D 0; + pdata->cal_config__vcsel_start =3D 0; + pdata->vcsel_width =3D 0; + pdata->VL53LX_p_005 =3D 0; + pdata->VL53LX_p_015 =3D 0; + pdata->total_periods_elapsed =3D 0; + pdata->min_bin_value =3D 0; + pdata->max_bin_value =3D 0; + pdata->zero_distance_phase =3D 0; + pdata->number_of_ambient_samples =3D 0; + pdata->ambient_events_sum =3D 0; + pdata->VL53LX_p_028 =3D 0; + + for (i =3D 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++) + pdata->bin_seq[i] =3D (uint8_t)i; + + for (i =3D 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++) + pdata->bin_rep[i] =3D 1; + + for (i =3D 0; i < VL53LX_HISTOGRAM_BUFFER_SIZE; i++) + if (i < VL53LX_p_021) + pdata->bin_data[i] =3D bin_value; + else + pdata->bin_data[i] =3D 0; +} + +void VL53LX_init_xtalk_bin_data_struct(uint32_t bin_value, uint16_t VL53LX= _p_021, VL53LX_xtalk_histogram_shape_t *pdata) +{ + uint16_t i =3D 0; + + pdata->zone_id =3D 0; + pdata->time_stamp =3D 0; + pdata->VL53LX_p_019 =3D 0; + pdata->VL53LX_p_020 =3D VL53LX_XTALK_HISTO_BINS; + pdata->VL53LX_p_021 =3D (uint8_t)VL53LX_p_021; + pdata->phasecal_result__reference_phase =3D 0; + pdata->phasecal_result__vcsel_start =3D 0; + pdata->cal_config__vcsel_start =3D 0; + pdata->vcsel_width =3D 0; + pdata->VL53LX_p_015 =3D 0; + pdata->zero_distance_phase =3D 0; + + for (i =3D 0; i < VL53LX_XTALK_HISTO_BINS; i++) { + if (i < VL53LX_p_021) + pdata->bin_data[i] =3D bin_value; + else + pdata->bin_data[i] =3D 0; + } +} + +VL53LX_Error VL53LX_xtalk_cal_data_init(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps =3D 0; + pdev->xtalk_cal.algo__crosstalk_compensation_x_plane_gradient_kcps =3D 0; + pdev->xtalk_cal.algo__crosstalk_compensation_y_plane_gradient_kcps =3D 0; + memset(&pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0], 0, sizeof(pde= v->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps)); + + return status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_output_init(VL53LX_LLDriverRe= sults_t *pres) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_smudge_corrector_data_t *pdata; + + pdata =3D &(pres->range_results.smudge_corrector_data); + + pdata->smudge_corr_valid =3D 0; + pdata->smudge_corr_clipped =3D 0; + pdata->single_xtalk_delta_flag =3D 0; + pdata->averaged_xtalk_delta_flag =3D 0; + pdata->sample_limit_exceeded_flag =3D 0; + pdata->gradient_zero_flag =3D 0; + pdata->new_xtalk_applied_flag =3D 0; + pdata->algo__crosstalk_compensation_plane_offset_kcps =3D 0; + pdata->algo__crosstalk_compensation_x_plane_gradient_kcps =3D 0; + pdata->algo__crosstalk_compensation_y_plane_gradient_kcps =3D 0; + + return status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_data_init(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev); + + pdev->smudge_correct_config.smudge_corr_enabled =3D 1; + pdev->smudge_correct_config.smudge_corr_apply_enabled =3D 1; + pdev->smudge_correct_config.smudge_corr_single_apply =3D VL53LX_TUNINGPA= RM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY_DEFAULT; + pdev->smudge_correct_config.smudge_margin =3D VL53LX_TUNINGPARM_DYNXTALK_= SMUDGE_MARGIN_DEFAULT; + pdev->smudge_correct_config.noise_margin =3D VL53LX_TUNINGPARM_DYNXTALK_N= OISE_MARGIN_DEFAULT; + pdev->smudge_correct_config.user_xtalk_offset_limit =3D VL53LX_TUNINGPARM= _DYNXTALK_XTALK_OFFSET_LIMIT_DEFAULT; + pdev->smudge_correct_config.user_xtalk_offset_limit_hi =3D VL53LX_TUNINGP= ARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI_DEFAULT; + pdev->smudge_correct_config.sample_limit =3D VL53LX_TUNINGPARM_DYNXTALK_S= AMPLE_LIMIT_DEFAULT; + pdev->smudge_correct_config.single_xtalk_delta =3D VL53LX_TUNINGPARM_DYNX= TALK_SINGLE_XTALK_DELTA_DEFAULT; + pdev->smudge_correct_config.averaged_xtalk_delta =3D VL53LX_TUNINGPARM_DY= NXTALK_AVERAGED_XTALK_DELTA_DEFAULT; + pdev->smudge_correct_config.smudge_corr_clip_limit =3D VL53LX_TUNINGPARM_= DYNXTALK_CLIP_LIMIT_DEFAULT; + pdev->smudge_correct_config.smudge_corr_ambient_threshold =3D VL53LX_TUNI= NGPARM_DYNXTALK_XTALK_AMB_THRESHOLD_DEFAULT; + pdev->smudge_correct_config.scaler_calc_method =3D 0; + pdev->smudge_correct_config.x_gradient_scaler =3D VL53LX_TUNINGPARM_DYNXT= ALK_XGRADIENT_SCALER_DEFAULT; + pdev->smudge_correct_config.y_gradient_scaler =3D VL53LX_TUNINGPARM_DYNXT= ALK_YGRADIENT_SCALER_DEFAULT; + pdev->smudge_correct_config.user_scaler_set =3D VL53LX_TUNINGPARM_DYNXTAL= K_USER_SCALER_SET_DEFAULT; + pdev->smudge_correct_config.nodetect_ambient_threshold =3D VL53LX_TUNINGP= ARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS_DEFAULT; + pdev->smudge_correct_config.nodetect_sample_limit =3D VL53LX_TUNINGPARM_D= YNXTALK_NODETECT_SAMPLE_LIMIT_DEFAULT; + pdev->smudge_correct_config.nodetect_xtalk_offset =3D VL53LX_TUNINGPARM_D= YNXTALK_NODETECT_XTALK_OFFSET_KCPS_DEFAULT; + pdev->smudge_correct_config.nodetect_min_range_mm =3D VL53LX_TUNINGPARM_D= YNXTALK_NODETECT_MIN_RANGE_MM_DEFAULT; + pdev->smudge_correct_config.max_smudge_factor =3D VL53LX_TUNINGPARM_DYNXT= ALK_MAX_SMUDGE_FACTOR_DEFAULT; + pdev->smudge_corrector_internals.current_samples =3D 0; + pdev->smudge_corrector_internals.required_samples =3D 0; + pdev->smudge_corrector_internals.accumulator =3D 0; + pdev->smudge_corrector_internals.nodetect_counter =3D 0; + + VL53LX_dynamic_xtalk_correction_output_init(pres); + + return status; +} + +VL53LX_Error VL53LX_low_power_auto_data_init(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->low_power_auto_data.vhv_loop_bound =3D VL53LX_TUNINGPARM_LOWPOWERAU= TO_VHV_LOOP_BOUND_DEFAULT; + pdev->low_power_auto_data.is_low_power_auto_mode =3D 0; + pdev->low_power_auto_data.low_power_auto_range_count =3D 0; + pdev->low_power_auto_data.saved_interrupt_config =3D 0; + pdev->low_power_auto_data.saved_vhv_init =3D 0; + pdev->low_power_auto_data.saved_vhv_timeout =3D 0; + pdev->low_power_auto_data.first_run_phasecal_result =3D 0; + pdev->low_power_auto_data.dss__total_rate_per_spad_mcps =3D 0; + pdev->low_power_auto_data.dss__required_spads =3D 0; + + return status; +} + +VL53LX_Error VL53LX_data_init(VL53LX_DEV Dev, uint8_t read_p2p_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev); + VL53LX_zone_objects_t *pobjects; + uint8_t i =3D 0; + + VL53LX_init_ll_driver_state(Dev, VL53LX_DEVICESTATE_UNKNOWN); + + pres->range_results.max_results =3D VL53LX_MAX_RANGE_RESULTS; + pres->range_results.active_results =3D 0; + pres->zone_results.max_zones =3D VL53LX_MAX_USER_ZONES; + pres->zone_results.active_zones =3D 0; + + for (i =3D 0; i < VL53LX_MAX_USER_ZONES; i++) { + pobjects =3D &(pres->zone_results.VL53LX_p_003[i]); + pobjects->xmonitor.VL53LX_p_016 =3D 0; + pobjects->xmonitor.VL53LX_p_017 =3D 0; + pobjects->xmonitor.VL53LX_p_011 =3D 0; + pobjects->xmonitor.range_status =3D VL53LX_DEVICEERROR_NOUPDATE; + } + + pres->zone_hists.max_zones =3D VL53LX_MAX_USER_ZONES; + pres->zone_hists.active_zones =3D 0; + + pres->zone_cal.max_zones =3D VL53LX_MAX_USER_ZONES; + + pres->zone_cal.active_zones =3D 0; + for (i =3D 0; i < VL53LX_MAX_USER_ZONES; i++) { + pres->zone_cal.VL53LX_p_003[i].no_of_samples =3D 0; + pres->zone_cal.VL53LX_p_003[i].effective_spads =3D 0; + pres->zone_cal.VL53LX_p_003[i].peak_rate_mcps =3D 0; + pres->zone_cal.VL53LX_p_003[i].median_range_mm =3D 0; + pres->zone_cal.VL53LX_p_003[i].range_mm_offset =3D 0; + } + + pdev->wait_method =3D VL53LX_WAIT_METHOD_BLOCKING; + pdev->preset_mode =3D VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE; + pdev->zone_preset =3D 0; + pdev->measurement_mode =3D VL53LX_DEVICEMEASUREMENTMODE_STOP; + + pdev->offset_calibration_mode =3D VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__= STANDARD; + pdev->offset_correction_mode =3D VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OF= FSETS; + pdev->dmax_mode =3D VL53LX_DEVICEDMAXMODE__FMT_CAL_DATA; + + pdev->phasecal_config_timeout_us =3D 1000; + pdev->mm_config_timeout_us =3D 2000; + pdev->range_config_timeout_us =3D 13000; + pdev->inter_measurement_period_ms =3D 100; + pdev->dss_config__target_total_rate_mcps =3D 0x0A00; + pdev->debug_mode =3D 0x00; + + pdev->offset_results.max_results =3D VL53LX_MAX_OFFSET_RANGE_RESULTS; + pdev->offset_results.active_results =3D 0; + + pdev->gain_cal.standard_ranging_gain_factor =3D VL53LX_TUNINGPARM_LITE_RA= NGING_GAIN_FACTOR_DEFAULT; + pdev->gain_cal.histogram_ranging_gain_factor =3D VL53LX_TUNINGPARM_HIST_G= AIN_FACTOR_DEFAULT; + + VL53LX_init_version(Dev); + + memset(pdev->multi_bins_rec, 0, sizeof(pdev->multi_bins_rec)); + pdev->bin_rec_pos =3D 0; + pdev->pos_before_next_recom =3D 0; + + if (read_p2p_data > 0 && status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_read_p2p_data(Dev); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_refspadchar_config_struct(&(pdev->refspadchar)); + + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_ssc_config_struct(&(pdev->ssc_cfg)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_xtalk_config_struct(&(pdev->customer), &(pdev->xt= alk_cfg)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_xtalk_extract_config_struct(&(pdev->xtalk_extract= _cfg)); + + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_offset_cal_config_struct(&(pdev->offsetcal_cfg)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_zone_cal_config_struct(&(pdev->zonecal_cfg)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_hist_post_process_config_struct(pdev->xtalk_cfg.g= lobal_crosstalk_compensation_enable, &(pdev->histpostprocess)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_hist_gen3_dmax_config_struct(&(pdev->dmax_cfg)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_tuning_parm_storage_struct(&(pdev->tuning_parms)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_set_preset_mode(Dev, pdev->preset_mode, pdev->dss_conf= ig__target_total_rate_mcps, pdev->phasecal_config_timeout_us, pdev->mm_conf= ig_timeout_us, pdev->range_config_timeout_us, pdev->inter_measurement_perio= d_ms); + + VL53LX_init_histogram_bin_data_struct(0, VL53LX_HISTOGRAM_BUFFER_SIZE, &(= pdev->hist_data)); + VL53LX_init_histogram_bin_data_struct(0, VL53LX_HISTOGRAM_BUFFER_SIZE, &(= pdev->hist_xtalk)); + VL53LX_init_xtalk_bin_data_struct(0, VL53LX_XTALK_HISTO_BINS, &(pdev->xta= lk_shapes.xtalk_shape)); + VL53LX_xtalk_cal_data_init(Dev); + VL53LX_dynamic_xtalk_correction_data_init(Dev); + VL53LX_low_power_auto_data_init(Dev); + + return status; +} + +VL53LX_Error VL53LX_set_dmax_mode(VL53LX_DEV Dev, VL53LX_DeviceDmaxMode dm= ax_mode) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->dmax_mode =3D dmax_mode; + + return status; +} + +VL53LX_Error VL53LX_DataInit(VL53LX_DEV Dev) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev; + uint8_t measurement_mode; + +#ifdef USE_I2C_2V8 + Status =3D VL53LX_RdByte(Dev, VL53LX_PAD_I2C_HV__EXTSUP_CONFIG, &i); + if (Status =3D=3D VL53LX_ERROR_NONE) { + i =3D (i & 0xfe) | 0x01; + Status =3D VL53LX_WrByte(Dev, VL53LX_PAD_I2C_HV__EXTSUP_CONFIG, i); + } +#endif + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_data_init(Dev, 1); + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D SetPresetModeL3CX(Dev, VL53LX_DISTANCEMODE_MEDIUM, 1000); + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_SetMeasurementTimingBudgetMicroSeconds(Dev, 33333); + + if (Status =3D=3D VL53LX_ERROR_NONE) { + pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data)); + } + + if (Status =3D=3D VL53LX_ERROR_NONE) { + Status =3D VL53LX_set_dmax_mode(Dev, VL53LX_DEVICEDMAXMODE__CUST_CAL_DAT= A); + } + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_SmudgeCorrectionEnable(Dev, VL53LX_SMUDGE_CORRECTION_N= ONE); + + measurement_mode =3D VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + VL53LXDevDataSet(Dev, LLData.measurement_mode, measurement_mode); + + VL53LXDevDataSet(Dev, CurrentParameters.DistanceMode, VL53LX_DISTANCEMODE= _MEDIUM); + + return Status; +} + +VL53LX_Error VL53LX_get_zone_config(VL53LX_DEV Dev, VL53LX_zone_config_t *= pzone_cfg) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + memcpy(pzone_cfg, &(pdev->zone_cfg), sizeof(VL53LX_zone_config_t)); + + return status; +} + +VL53LX_Error VL53LX_GetUserROI(VL53LX_DEV Dev, VL53LX_UserRoi_t *pRoi) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_zone_config_t zone_cfg; + uint8_t TopLeftX; + uint8_t TopLeftY; + uint8_t BotRightX; + uint8_t BotRightY; + + VL53LX_get_zone_config(Dev, &zone_cfg); + + TopLeftX =3D (2 * zone_cfg.user_zones[0].x_centre - zone_cfg.user_zones[0= ].width) >> 1; + TopLeftY =3D (2 * zone_cfg.user_zones[0].y_centre + zone_cfg.user_zones[0= ].height) >> 1; + BotRightX =3D (2 * zone_cfg.user_zones[0].x_centre + zone_cfg.user_zones[= 0].width) >> 1; + BotRightY =3D (2 * zone_cfg.user_zones[0].y_centre - zone_cfg.user_zones[= 0].height) >> 1; + pRoi->TopLeftX =3D TopLeftX; + pRoi->TopLeftY =3D TopLeftY; + pRoi->BotRightX =3D BotRightX; + pRoi->BotRightY =3D BotRightY; + + return Status; +} + +VL53LX_Error VL53LX_GetDeviceInfo(VL53LX_DEV Dev, VL53LX_DeviceInfo_t *pVL= 53LX_DeviceInfo) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + uint8_t revision_id; + VL53LX_LLDriverData_t *pLLData; + + pLLData =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pVL53LX_DeviceInfo->ProductType =3D pLLData->nvm_copy_data.identification= __module_type; + + revision_id =3D pLLData->nvm_copy_data.identification__revision_id; + pVL53LX_DeviceInfo->ProductRevisionMajor =3D 1; + pVL53LX_DeviceInfo->ProductRevisionMinor =3D (revision_id & 0xF0) >> 4; + + return Status; +} + +VL53LX_Error VL53LX_GetOpticalCenter(VL53LX_DEV Dev, FixPoint1616_t *pOpti= calCenterX, FixPoint1616_t *pOpticalCenterY) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_calibration_data_t CalibrationData; + + *pOpticalCenterX =3D 0; + *pOpticalCenterY =3D 0; + Status =3D VL53LX_get_part_to_part_data(Dev, &CalibrationData); + if (Status =3D=3D VL53LX_ERROR_NONE) { + *pOpticalCenterX =3D VL53LX_FIXPOINT44TOFIXPOINT1616(CalibrationData.opt= ical_centre.x_centre); + *pOpticalCenterY =3D VL53LX_FIXPOINT44TOFIXPOINT1616(CalibrationData.opt= ical_centre.y_centre); + } + return Status; +} + +static int setup_tunings(struct stmvl53lx_data *data) +{ + int rc =3D 0; + int i; + + for (i =3D 0; i < ARRAY_SIZE(tunings); i++) { + rc =3D VL53LX_SetTuningParameter(&data->stdev, tunings[i][0], + tunings[i][1]); + if (rc) { + rc =3D store_last_error(data, rc); + break; + } + } + return rc; +} + +static int allocate_dev_id(void) +{ + int i; + + mutex_lock(&dev_table_mutex); + + for (i =3D 0; i < STMVL53LX_CFG_MAX_DEV; i++) + if (!stmvl53lx_dev_table[i]) + break; + i =3D i < STMVL53LX_CFG_MAX_DEV ? i : -1; + + mutex_unlock(&dev_table_mutex); + + return i; +} + +static void deallocate_dev_id(int id) +{ + mutex_lock(&dev_table_mutex); + + stmvl53lx_dev_table[id] =3D NULL; + + mutex_unlock(&dev_table_mutex); +} + +static void vl53lx_diff_histo_stddev(VL53LX_LLDriverData_t *pdev, + VL53LX_histogram_bin_data_t *pdata, uint8_t timing, uint8_t HighIndex, + uint8_t prev_pos, int32_t *pdiff_histo_stddev) +{ + uint16_t bin =3D 0; + int32_t total_rate_pre =3D 0; + int32_t total_rate_cur =3D 0; + int32_t PrevBin, CurrBin; + + total_rate_pre =3D 0; + total_rate_cur =3D 0; + + + for (bin =3D timing * 4; bin < HighIndex; bin++) { + total_rate_pre +=3D pdev->multi_bins_rec[prev_pos][timing][bin]; + total_rate_cur +=3D pdata->bin_data[bin]; + } + + if ((total_rate_pre !=3D 0) && (total_rate_cur !=3D 0)) + for (bin =3D timing * 4; bin < HighIndex; bin++) { + PrevBin =3D pdev->multi_bins_rec[prev_pos][timing][bin]; + PrevBin =3D (PrevBin * 1000) / total_rate_pre; + CurrBin =3D pdata->bin_data[bin] * 1000 / total_rate_cur; + *pdiff_histo_stddev +=3D (PrevBin - CurrBin) * (PrevBin - CurrBin); + } +} + +static void vl53lx_histo_merge(VL53LX_DEV Dev, VL53LX_histogram_bin_data_t= *pdata) +{ + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + uint16_t bin =3D 0; + uint8_t i =3D 0; + int32_t TuningBinRecSize =3D 0; + uint8_t recom_been_reset =3D 0; + uint8_t timing =3D 0; + int32_t rmt =3D 0; + int32_t diff_histo_stddev =3D 0; + uint8_t HighIndex, prev_pos; + uint8_t BuffSize =3D VL53LX_HISTOGRAM_BUFFER_SIZE; + uint8_t pos; + + VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, &Tunin= gBinRecSize); + VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD, &rmt= ); + + if (pdev->pos_before_next_recom =3D=3D 0) { + timing =3D 1 - pdata->result__stream_count % 2; + + diff_histo_stddev =3D 0; + HighIndex =3D BuffSize - timing * 4; + if (pdev->bin_rec_pos > 0) + prev_pos =3D pdev->bin_rec_pos - 1; + else + prev_pos =3D (TuningBinRecSize - 1); + + if (pdev->multi_bins_rec[prev_pos][timing][4] > 0) + vl53lx_diff_histo_stddev(pdev, pdata, timing, HighIndex, prev_pos, &dif= f_histo_stddev); + + if (diff_histo_stddev >=3D rmt) { + memset(pdev->multi_bins_rec, 0, sizeof(pdev->multi_bins_rec)); + pdev->bin_rec_pos =3D 0; + recom_been_reset =3D 1; + if (timing =3D=3D 0) + pdev->pos_before_next_recom =3D VL53LX_FRAME_WAIT_EVENT; + else + pdev->pos_before_next_recom =3D VL53LX_FRAME_WAIT_EVENT + 1; + } else { + pos =3D pdev->bin_rec_pos; + for (i =3D 0; i < BuffSize; i++) + pdev->multi_bins_rec[pos][timing][i] =3D pdata->bin_data[i]; + } + if (pdev->bin_rec_pos =3D=3D (TuningBinRecSize - 1) && timing =3D=3D 1) + pdev->bin_rec_pos =3D 0; + else if (timing =3D=3D 1) + pdev->bin_rec_pos++; + + if (!((recom_been_reset =3D=3D 1) && (timing =3D=3D 0)) && + (pdev->pos_before_next_recom =3D=3D 0)) { + + for (bin =3D 0; bin < BuffSize; bin++) + pdata->bin_data[bin] =3D 0; + + for (bin =3D 0; bin < BuffSize; bin++) + for (i =3D 0; i < TuningBinRecSize; i++) + pdata->bin_data[bin] +=3D (pdev->multi_bins_rec[i][timing][bin]); + } + } else { + + pdev->pos_before_next_recom--; + if (pdev->pos_before_next_recom =3D=3D 255) + pdev->pos_before_next_recom =3D 0; + } +} + +void VL53LX_hist_get_bin_sequence_config(VL53LX_DEV Dev, VL53LX_histogram_= bin_data_t *pdata) +{ + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + int32_t amb_thresh_low =3D 0; + int32_t amb_thresh_high =3D 0; + uint8_t i =3D 0; + + amb_thresh_low =3D 1024 * (int32_t)pdev->hist_cfg.histogram_config__amb_= thresh_low; + amb_thresh_high =3D 1024 * (int32_t)pdev->hist_cfg.histogram_config__amb_= thresh_high; + + if ((pdev->ll_state.rd_stream_count & 0x01) =3D=3D 0) { + pdata->bin_seq[5] =3D pdev->hist_cfg.histogram_config__mid_amb_even_bin_= 4_5 >> 4; + pdata->bin_seq[4] =3D pdev->hist_cfg.histogram_config__mid_amb_even_bin_= 4_5 & 0x0F; + pdata->bin_seq[3] =3D pdev->hist_cfg.histogram_config__mid_amb_even_bin_= 2_3 >> 4; + pdata->bin_seq[2] =3D pdev->hist_cfg.histogram_config__mid_amb_even_bin_= 2_3 & 0x0F; + pdata->bin_seq[1] =3D pdev->hist_cfg.histogram_config__mid_amb_even_bin_= 0_1 >> 4; + pdata->bin_seq[0] =3D pdev->hist_cfg.histogram_config__mid_amb_even_bin_= 0_1 & 0x0F; + + if (pdata->ambient_events_sum > amb_thresh_high) { + pdata->bin_seq[5] =3D pdev->hist_cfg.histogram_config__high_amb_even_bi= n_4_5 >> 4; + pdata->bin_seq[4] =3D pdev->hist_cfg.histogram_config__high_amb_even_bi= n_4_5 & 0x0F; + pdata->bin_seq[3] =3D pdev->hist_cfg.histogram_config__high_amb_even_bi= n_2_3 >> 4; + pdata->bin_seq[2] =3D pdev->hist_cfg.histogram_config__high_amb_even_bi= n_2_3 & 0x0F; + pdata->bin_seq[1] =3D pdev->hist_cfg.histogram_config__high_amb_even_bi= n_0_1 >> 4; + pdata->bin_seq[0] =3D pdev->hist_cfg.histogram_config__high_amb_even_bi= n_0_1 & 0x0F; + } + if (pdata->ambient_events_sum < amb_thresh_low) { + pdata->bin_seq[5] =3D pdev->hist_cfg.histogram_config__low_amb_even_bin= _4_5 >> 4; + pdata->bin_seq[4] =3D pdev->hist_cfg.histogram_config__low_amb_even_bin= _4_5 & 0x0F; + pdata->bin_seq[3] =3D pdev->hist_cfg.histogram_config__low_amb_even_bin= _2_3 >> 4; + pdata->bin_seq[2] =3D pdev->hist_cfg.histogram_config__low_amb_even_bin= _2_3 & 0x0F; + pdata->bin_seq[1] =3D pdev->hist_cfg.histogram_config__low_amb_even_bin= _0_1 >> 4; + pdata->bin_seq[0] =3D pdev->hist_cfg.histogram_config__low_amb_even_bin= _0_1 & 0x0F; + } + + } else { + pdata->bin_seq[5] =3D pdev->hist_cfg.histogram_config__mid_amb_odd_bin_5= & 0x0F; + pdata->bin_seq[4] =3D pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3= _4 & 0x0F; + pdata->bin_seq[3] =3D pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3= _4 >> 4; + pdata->bin_seq[2] =3D pdev->hist_cfg.histogram_config__mid_amb_odd_bin_2= & 0x0F; + pdata->bin_seq[1] =3D pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0= _1 >> 4; + pdata->bin_seq[0] =3D pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0= _1 & 0x0F; + if (pdata->ambient_events_sum > amb_thresh_high) { + pdata->bin_seq[5] =3D pdev->hist_cfg.histogram_config__high_amb_odd_bin= _4_5 >> 4; + pdata->bin_seq[4] =3D pdev->hist_cfg.histogram_config__high_amb_odd_bin= _4_5 & 0x0F; + pdata->bin_seq[3] =3D pdev->hist_cfg.histogram_config__high_amb_odd_bin= _2_3 >> 4; + pdata->bin_seq[2] =3D pdev->hist_cfg.histogram_config__high_amb_odd_bin= _2_3 & 0x0F; + pdata->bin_seq[1] =3D pdev->hist_cfg.histogram_config__high_amb_odd_bin= _0_1 >> 4; + pdata->bin_seq[0] =3D pdev->hist_cfg.histogram_config__high_amb_odd_bin= _0_1 & 0x0F; + } + if (pdata->ambient_events_sum < amb_thresh_low) { + pdata->bin_seq[5] =3D pdev->hist_cfg.histogram_config__low_amb_odd_bin_= 4_5 >> 4; + pdata->bin_seq[4] =3D pdev->hist_cfg.histogram_config__low_amb_odd_bin_= 4_5 & 0x0F; + pdata->bin_seq[3] =3D pdev->hist_cfg.histogram_config__low_amb_odd_bin_= 2_3 >> 4; + pdata->bin_seq[2] =3D pdev->hist_cfg.histogram_config__low_amb_odd_bin_= 2_3 & 0x0F; + pdata->bin_seq[1] =3D pdev->hist_cfg.histogram_config__low_amb_odd_bin_= 0_1 >> 4; + pdata->bin_seq[0] =3D pdev->hist_cfg.histogram_config__low_amb_odd_bin_= 0_1 & 0x0F; + } + } + for (i =3D 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++) + pdata->bin_rep[i] =3D 1; +} + +uint32_t VL53LX_duration_maths(uint32_t pll_period_us, uint32_t vcsel_parm= _pclks, uint32_t window_vclks, uint32_t elapsed_mclks) +{ + uint64_t tmp_long_int =3D 0; + uint32_t duration_us =3D 0; + + duration_us =3D window_vclks * pll_period_us; + duration_us =3D duration_us >> 12; + tmp_long_int =3D (uint64_t)duration_us; + duration_us =3D elapsed_mclks * vcsel_parm_pclks; + duration_us =3D duration_us >> 4; + tmp_long_int =3D tmp_long_int * (uint64_t)duration_us; + tmp_long_int =3D tmp_long_int >> 12; + if (tmp_long_int > 0xFFFFFFFF) + tmp_long_int =3D 0xFFFFFFFF; + + duration_us =3D (uint32_t)tmp_long_int; + return duration_us; +} + +void VL53LX_hist_calc_zero_distance_phase(VL53LX_histogram_bin_data_t *pda= ta) +{ + uint32_t period =3D 0; + uint32_t VL53LX_p_014 =3D 0; + + period =3D 2048 * (uint32_t)VL53LX_decode_vcsel_period(pdata->VL53LX_p_00= 5); + + VL53LX_p_014 =3D period; + VL53LX_p_014 +=3D (uint32_t)pdata->phasecal_result__reference_phase; + VL53LX_p_014 +=3D (2048 * (uint32_t)pdata->phasecal_result__vcsel_start); + VL53LX_p_014 -=3D (2048 * (uint32_t)pdata->cal_config__vcsel_start); + + if (period !=3D 0) + VL53LX_p_014 =3D VL53LX_p_014 % period; + else + VL53LX_p_014 =3D 0; + + pdata->zero_distance_phase =3D (uint16_t)VL53LX_p_014; +} + +void VL53LX_hist_estimate_ambient_from_ambient_bins(VL53LX_histogram_bin_d= ata_t *pdata) +{ + uint8_t bin =3D 0; + + if (pdata->number_of_ambient_bins > 0) { + pdata->number_of_ambient_samples =3D pdata->number_of_ambient_bins; + pdata->ambient_events_sum =3D 0; + for (bin =3D 0; bin < pdata->number_of_ambient_bins; bin++) + pdata->ambient_events_sum +=3D pdata->bin_data[bin]; + + pdata->VL53LX_p_028 =3D pdata->ambient_events_sum; + pdata->VL53LX_p_028 +=3D ((int32_t)pdata->number_of_ambient_bins / 2); + pdata->VL53LX_p_028 /=3D (int32_t)pdata->number_of_ambient_bins; + } +} + +VL53LX_Error VL53LX_get_histogram_bin_data(VL53LX_DEV Dev, VL53LX_histogra= m_bin_data_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev); + VL53LX_zone_private_dyn_cfg_t *pzone_dyn_cfg; + VL53LX_static_nvm_managed_t *pstat_nvm =3D &(pdev->stat_nvm); + VL53LX_static_config_t *pstat_cfg =3D &(pdev->stat_cfg); + VL53LX_general_config_t *pgen_cfg =3D &(pdev->gen_cfg); + VL53LX_timing_config_t *ptim_cfg =3D &(pdev->tim_cfg); + VL53LX_range_results_t *presults =3D &(pres->range_results); + + uint8_t buffer[VL53LX_MAX_I2C_XFER_SIZE]; + uint8_t *pbuffer =3D &buffer[0]; + uint8_t bin_23_0 =3D 0x00; + uint16_t bin =3D 0; + uint16_t i2c_buffer_offset_bytes =3D 0; + uint16_t encoded_timeout =3D 0; + + uint32_t pll_period_us =3D 0; + uint32_t periods_elapsed_tmp =3D 0; + + uint8_t i =3D 0; + + int32_t hist_merge =3D 0; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_ReadMulti(Dev, VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX, pb= uffer, VL53LX_HISTOGRAM_BIN_DATA_I2C_SIZE_BYTES); + + pdata->result__interrupt_status =3D *(pbuffer + 0); + pdata->result__range_status =3D *(pbuffer + 1); + pdata->result__report_status =3D *(pbuffer + 2); + pdata->result__stream_count =3D *(pbuffer + 3); + pdata->result__dss_actual_effective_spads =3D VL53LX_i2c_decode_uint16_t(= 2, pbuffer + 4); + + i2c_buffer_offset_bytes =3D VL53LX_PHASECAL_RESULT__REFERENCE_PHASE - VL5= 3LX_HISTOGRAM_BIN_DATA_I2C_INDEX; + + pbuffer =3D &buffer[i2c_buffer_offset_bytes]; + + pdata->phasecal_result__reference_phase =3D VL53LX_i2c_decode_uint16_t(2,= pbuffer); + + i2c_buffer_offset_bytes =3D VL53LX_PHASECAL_RESULT__VCSEL_START - VL53LX_= HISTOGRAM_BIN_DATA_I2C_INDEX; + + pdata->phasecal_result__vcsel_start =3D buffer[i2c_buffer_offset_bytes]; + + pdev->dbg_results.phasecal_result__reference_phase =3D pdata->phasecal_re= sult__reference_phase; + pdev->dbg_results.phasecal_result__vcsel_start =3D pdata->phasecal_result= __vcsel_start; + + i2c_buffer_offset_bytes =3D VL53LX_RESULT__HISTOGRAM_BIN_23_0_MSB - VL53L= X_HISTOGRAM_BIN_DATA_I2C_INDEX; + + bin_23_0 =3D buffer[i2c_buffer_offset_bytes] << 2; + + i2c_buffer_offset_bytes =3D VL53LX_RESULT__HISTOGRAM_BIN_23_0_LSB - VL53L= X_HISTOGRAM_BIN_DATA_I2C_INDEX; + + bin_23_0 +=3D buffer[i2c_buffer_offset_bytes]; + + i2c_buffer_offset_bytes =3D VL53LX_RESULT__HISTOGRAM_BIN_23_0 - VL53LX_HI= STOGRAM_BIN_DATA_I2C_INDEX; + + buffer[i2c_buffer_offset_bytes] =3D bin_23_0; + + i2c_buffer_offset_bytes =3D VL53LX_RESULT__HISTOGRAM_BIN_0_2 - VL53LX_HIS= TOGRAM_BIN_DATA_I2C_INDEX; + + pbuffer =3D &buffer[i2c_buffer_offset_bytes]; + for (bin =3D 0; bin < VL53LX_HISTOGRAM_BUFFER_SIZE; bin++) { + pdata->bin_data[bin] =3D (int32_t)VL53LX_i2c_decode_uint32_t(3, pbuffer); + pbuffer +=3D 3; + } + + VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE, &hist_merge); + if (pdata->result__stream_count =3D=3D 0) { + + memset(pdev->multi_bins_rec, 0, sizeof(pdev->multi_bins_rec)); + pdev->bin_rec_pos =3D 0; + pdev->pos_before_next_recom =3D 0; + } + if (hist_merge =3D=3D 1) + vl53lx_histo_merge(Dev, pdata); + + pdata->zone_id =3D pdev->ll_state.rd_zone_id; + pdata->VL53LX_p_019 =3D 0; + pdata->VL53LX_p_020 =3D VL53LX_HISTOGRAM_BUFFER_SIZE; + pdata->VL53LX_p_021 =3D VL53LX_HISTOGRAM_BUFFER_SIZE; + + pdata->cal_config__vcsel_start =3D pgen_cfg->cal_config__vcsel_start; + + + + pdata->vcsel_width =3D ((uint16_t)pgen_cfg->global_config__vcsel_width) <= < 4; + pdata->vcsel_width +=3D (uint16_t)pstat_cfg->ana_config__vcsel_pulse_widt= h_offset; + + pdata->VL53LX_p_015 =3D pstat_nvm->osc_measured__fast_osc__frequency; + + VL53LX_hist_get_bin_sequence_config(Dev, pdata); + + if (pdev->ll_state.rd_timing_status =3D=3D 0) { + encoded_timeout =3D (ptim_cfg->range_config__timeout_macrop_a_hi << 8) += ptim_cfg->range_config__timeout_macrop_a_lo; + pdata->VL53LX_p_005 =3D ptim_cfg->range_config__vcsel_period_a; + } else { + encoded_timeout =3D (ptim_cfg->range_config__timeout_macrop_b_hi << 8) += ptim_cfg->range_config__timeout_macrop_b_lo; + pdata->VL53LX_p_005 =3D ptim_cfg->range_config__vcsel_period_b; + } + + pdata->number_of_ambient_bins =3D 0; + for (i =3D 0; i < 6; i++) { + if ((pdata->bin_seq[i] & 0x07) =3D=3D 0x07) + pdata->number_of_ambient_bins =3D pdata->number_of_ambient_bins + 0x04; + } + pdata->total_periods_elapsed =3D VL53LX_decode_timeout(encoded_timeout); + + pll_period_us =3D VL53LX_calc_pll_period_us(pdata->VL53LX_p_015); + + periods_elapsed_tmp =3D pdata->total_periods_elapsed + 1; + + pdata->peak_duration_us =3D VL53LX_duration_maths(pll_period_us, (uint32_= t)pdata->vcsel_width, VL53LX_RANGING_WINDOW_VCSEL_PERIODS, periods_elapsed_= tmp); + + pdata->woi_duration_us =3D 0; + + VL53LX_hist_calc_zero_distance_phase(pdata); + VL53LX_hist_estimate_ambient_from_ambient_bins(pdata); + + pdata->cfg_device_state =3D pdev->ll_state.cfg_device_state; + pdata->rd_device_state =3D pdev->ll_state.rd_device_state; + + pzone_dyn_cfg =3D &(pres->zone_dyn_cfgs.VL53LX_p_003[pdata->zone_id]); + + pdata->roi_config__user_roi_centre_spad =3D pzone_dyn_cfg->roi_config__us= er_roi_centre_spad; + pdata->roi_config__user_roi_requested_global_xy_size =3D pzone_dyn_cfg->r= oi_config__user_roi_requested_global_xy_size; + + presults->device_status =3D VL53LX_DEVICEERROR_NOUPDATE; + + switch (pdata->result__range_status & VL53LX_RANGE_STATUS__RANGE_STATUS_M= ASK) { + case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE: + case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE: + case VL53LX_DEVICEERROR_NOVHVVALUEFOUND: + case VL53LX_DEVICEERROR_USERROICLIP: + case VL53LX_DEVICEERROR_MULTCLIPFAIL: + presults->device_status =3D (pdata->result__range_status & VL53LX_RANGE_= STATUS__RANGE_STATUS_MASK); + status =3D VL53LX_ERROR_RANGE_ERROR; + break; + } + return status; +} + +VL53LX_Error VL53LX_hist_copy_and_scale_ambient_info(VL53LX_zone_hist_info= _t *pidata, VL53LX_histogram_bin_data_t *podata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + int64_t evts =3D 0; + int64_t tmpi =3D 0; + int64_t tmpo =3D 0; + + if (pidata->result__dss_actual_effective_spads =3D=3D 0) { + status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + } else { + if (pidata->number_of_ambient_bins > 0 && + podata->number_of_ambient_bins =3D=3D 0) { + tmpo =3D 1 + (int64_t)podata->total_periods_elapsed; + tmpo *=3D (int64_t)podata->result__dss_actual_effective_spads; + tmpi =3D 1 + (int64_t)pidata->total_periods_elapsed; + tmpi *=3D (int64_t)pidata->result__dss_actual_effective_spads; + evts =3D tmpo * (int64_t)pidata->ambient_events_sum; + evts +=3D (tmpi/2); + if (tmpi !=3D 0) + evts =3D do_division_s(evts, tmpi); + + podata->ambient_events_sum =3D (int32_t)evts; + podata->VL53LX_p_028 =3D podata->ambient_events_sum; + podata->VL53LX_p_028 +=3D ((int32_t)pidata->number_of_ambient_bins / 2); + podata->VL53LX_p_028 /=3D (int32_t)pidata->number_of_ambient_bins; + } + } + return status; +} + +VL53LX_Error VL53LX_compute_histo_merge_nb(VL53LX_DEV Dev, uint8_t *histo_= merge_nb) +{ + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t i, timing; + uint8_t sum =3D 0; + + timing =3D (pdev->hist_data.bin_seq[0] =3D=3D 7 ? 1 : 0); + for (i =3D 0; i < VL53LX_BIN_REC_SIZE; i++) + if (pdev->multi_bins_rec[i][timing][7] > 0) + sum++; + *histo_merge_nb =3D sum; + return status; +} + +void VL53LX_hist_combine_mm1_mm2_offsets( + int16_t mm1_offset_mm, + int16_t mm2_offset_mm, + uint8_t encoded_mm_roi_centre, + uint8_t encoded_mm_roi_size, + uint8_t encoded_zone_centre, + uint8_t encoded_zone_size, + VL53LX_additional_offset_cal_data_t *pcal_data, + uint8_t *pgood_spads, + uint16_t aperture_attenuation, + int16_t *prange_offset_mm) +{ + uint16_t max_mm_inner_effective_spads =3D 0; + uint16_t max_mm_outer_effective_spads =3D 0; + uint16_t mm_inner_effective_spads =3D 0; + uint16_t mm_outer_effective_spads =3D 0; + uint32_t scaled_mm1_peak_rate_mcps =3D 0; + uint32_t scaled_mm2_peak_rate_mcps =3D 0; + int32_t tmp0 =3D 0; + int32_t tmp1 =3D 0; + + VL53LX_calc_mm_effective_spads( + encoded_mm_roi_centre, + encoded_mm_roi_size, + 0xC7, + 0xFF, + pgood_spads, + aperture_attenuation, + &max_mm_inner_effective_spads, + &max_mm_outer_effective_spads); + + if ((max_mm_inner_effective_spads =3D=3D 0) || + (max_mm_outer_effective_spads =3D=3D 0)) + goto FAIL; + + VL53LX_calc_mm_effective_spads( + encoded_mm_roi_centre, + encoded_mm_roi_size, + encoded_zone_centre, + encoded_zone_size, + pgood_spads, + aperture_attenuation, + &mm_inner_effective_spads, + &mm_outer_effective_spads); + + scaled_mm1_peak_rate_mcps =3D (uint32_t)pcal_data->result__mm_inner_peak= _signal_count_rtn_mcps; + scaled_mm1_peak_rate_mcps *=3D (uint32_t)mm_inner_effective_spads; + scaled_mm1_peak_rate_mcps /=3D (uint32_t)max_mm_inner_effective_spads; + + scaled_mm2_peak_rate_mcps =3D (uint32_t)pcal_data->result__mm_outer_peak= _signal_count_rtn_mcps; + scaled_mm2_peak_rate_mcps *=3D (uint32_t)mm_outer_effective_spads; + scaled_mm2_peak_rate_mcps /=3D (uint32_t)max_mm_outer_effective_spads; + + tmp0 =3D ((int32_t)mm1_offset_mm * (int32_t)scaled_mm1_peak_rate_mcps); + tmp0 +=3D ((int32_t)mm2_offset_mm * (int32_t)scaled_mm2_peak_rate_mcps); + + tmp1 =3D (int32_t)scaled_mm1_peak_rate_mcps + (int32_t)scaled_mm2_peak_r= ate_mcps; + + if (tmp1 !=3D 0) + tmp0 =3D (tmp0 * 4) / tmp1; +FAIL: + *prange_offset_mm =3D (int16_t)tmp0; + +} + +static VL53LX_Error select_offset_per_vcsel(VL53LX_LLDriverData_t *pdev, i= nt16_t *poffset) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + int16_t tA, tB; + uint8_t isc; + + switch (pdev->preset_mode) { + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE: + tA =3D pdev->per_vcsel_cal_data.short_a_offset_mm; + tB =3D pdev->per_vcsel_cal_data.short_b_offset_mm; + break; + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE: + tA =3D pdev->per_vcsel_cal_data.medium_a_offset_mm; + tB =3D pdev->per_vcsel_cal_data.medium_b_offset_mm; + break; + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE: + tA =3D pdev->per_vcsel_cal_data.long_a_offset_mm; + tB =3D pdev->per_vcsel_cal_data.long_b_offset_mm; + break; + default: + tA =3D pdev->per_vcsel_cal_data.long_a_offset_mm; + tB =3D pdev->per_vcsel_cal_data.long_b_offset_mm; + status =3D VL53LX_ERROR_INVALID_PARAMS; + *poffset =3D 0; + break; + } + + isc =3D pdev->ll_state.cfg_internal_stream_count; + if (status =3D=3D VL53LX_ERROR_NONE) + *poffset =3D (isc & 0x01) ? tA : tB; + + return status; +} + +void VL53LX_calc_max_effective_spads(uint8_t encoded_zone_centre, uint8_t = encoded_zone_size, uint8_t *pgood_spads, uint16_t aperture_attenuation, uin= t16_t *pmax_effective_spads) +{ + int16_t x =3D 0; + int16_t y =3D 0; + int16_t zone_x_ll =3D 0; + int16_t zone_y_ll =3D 0; + int16_t zone_x_ur =3D 0; + int16_t zone_y_ur =3D 0; + uint8_t spad_number =3D 0; + uint8_t byte_index =3D 0; + uint8_t bit_index =3D 0; + uint8_t bit_mask =3D 0; + uint8_t is_aperture =3D 0; + + VL53LX_decode_zone_limits(encoded_zone_centre, encoded_zone_size, &zone_x= _ll, &zone_y_ll, &zone_x_ur, &zone_y_ur); + + *pmax_effective_spads =3D 0; + for (y =3D zone_y_ll; y <=3D zone_y_ur; y++) { + for (x =3D zone_x_ll; x <=3D zone_x_ur; x++) { + VL53LX_encode_row_col((uint8_t)y, (uint8_t)x, &spad_number); + VL53LX_spad_number_to_byte_bit_index(spad_number, &byte_index, &bit_ind= ex, &bit_mask); + if ((pgood_spads[byte_index] & bit_mask) > 0) { + is_aperture =3D VL53LX_is_aperture_location((uint8_t)y, (uint8_t)x); + if (is_aperture > 0) + *pmax_effective_spads +=3D aperture_attenuation; + else + *pmax_effective_spads +=3D 0x0100; + } + } + } +} + +VL53LX_Error VL53LX_get_dmax_calibration_data(VL53LX_DEV Dev, VL53LX_Devic= eDmaxMode dmax_mode, VL53LX_dmax_calibration_data_t *pdmax_cal) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + switch (dmax_mode) { + case VL53LX_DEVICEDMAXMODE__CUST_CAL_DATA: + memcpy(pdmax_cal, &(pdev->cust_dmax_cal), sizeof(VL53LX_dmax_calibration= _data_t)); + break; + case VL53LX_DEVICEDMAXMODE__FMT_CAL_DATA: + memcpy(pdmax_cal, &(pdev->fmt_dmax_cal), sizeof(VL53LX_dmax_calibration_= data_t)); + break; + default: + status =3D VL53LX_ERROR_INVALID_PARAMS; + break; + } + return status; +} + +VL53LX_Error VL53LX_f_031(VL53LX_histogram_bin_data_t *pidata, VL53LX_hist= ogram_bin_data_t *podata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t bin_initial_index[VL53LX_MAX_BIN_SEQUENCE_CODE+1]; + uint8_t bin_repeat_count[VL53LX_MAX_BIN_SEQUENCE_CODE+1]; + uint8_t bin_cfg =3D 0; + uint8_t bin_seq_length =3D 0; + int32_t repeat_count =3D 0; + uint8_t VL53LX_p_032 =3D 0; + uint8_t lc =3D 0; + uint8_t i =3D 0; + + memcpy(podata, pidata, sizeof(VL53LX_histogram_bin_data_t)); + + podata->VL53LX_p_021 =3D 0; + + for (lc =3D 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) + podata->bin_seq[lc] =3D VL53LX_MAX_BIN_SEQUENCE_CODE+1; + + for (lc =3D 0 ; lc < podata->VL53LX_p_020 ; lc++) + podata->bin_data[lc] =3D 0; + + for (lc =3D 0 ; lc <=3D VL53LX_MAX_BIN_SEQUENCE_CODE ; lc++) { + bin_initial_index[lc] =3D 0x00; + bin_repeat_count[lc] =3D 0x00; + } + + bin_seq_length =3D 0x00; + + for (lc =3D 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) { + bin_cfg =3D pidata->bin_seq[lc]; + + if (bin_repeat_count[bin_cfg] =3D=3D 0) { + bin_initial_index[bin_cfg] =3D bin_seq_length * 4; + podata->bin_seq[bin_seq_length] =3D bin_cfg; + bin_seq_length++; + } + bin_repeat_count[bin_cfg]++; + + VL53LX_p_032 =3D bin_initial_index[bin_cfg]; + + for (i =3D 0 ; i < 4 ; i++) + podata->bin_data[VL53LX_p_032+i] +=3D + pidata->bin_data[lc*4+i]; + + } + for (lc =3D 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) { + bin_cfg =3D podata->bin_seq[lc]; + + if (bin_cfg <=3D VL53LX_MAX_BIN_SEQUENCE_CODE) + podata->bin_rep[lc] =3D + bin_repeat_count[bin_cfg]; + else + podata->bin_rep[lc] =3D 0; + } + podata->VL53LX_p_021 =3D bin_seq_length * 4; + + for (lc =3D 0 ; lc <=3D VL53LX_MAX_BIN_SEQUENCE_CODE ; lc++) { + repeat_count =3D (int32_t)bin_repeat_count[lc]; + if (repeat_count > 0) { + VL53LX_p_032 =3D bin_initial_index[lc]; + for (i =3D 0 ; i < 4 ; i++) { + podata->bin_data[VL53LX_p_032+i] +=3D (repeat_count/2); + podata->bin_data[VL53LX_p_032+i] /=3D repeat_count; + } + } + } + podata->number_of_ambient_bins =3D 0; + if ((bin_repeat_count[7] > 0) || (bin_repeat_count[15] > 0)) + podata->number_of_ambient_bins =3D 4; + + return status; +} + +VL53LX_Error VL53LX_f_032(uint32_t mean_offset, int16_t xgradient, int16_t= ygradient, int8_t centre_offset_x, int8_t centre_offset_y, uint16_t roi_ef= fective_spads, uint8_t roi_centre_spad, uint8_t roi_xy_size, uint32_t *xtal= k_rate_kcps) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + uint8_t row =3D 0; + uint8_t col =3D 0; + int16_t bound_l_x =3D 0; + int16_t bound_r_x =3D 0; + int16_t bound_u_y =3D 0; + int16_t bound_d_y =3D 0; + int64_t xtalk_rate_ll =3D 0; + int64_t xtalk_rate_ur =3D 0; + int64_t xtalk_avg =3D 0; + + if (status =3D=3D VL53LX_ERROR_NONE) { + VL53LX_decode_row_col(roi_centre_spad, &row, &col); + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + if ((((int16_t)roi_xy_size / 16) & 0x01) =3D=3D 1) + bound_l_x =3D (int16_t) col - (((int16_t)roi_xy_size / 32) + 1); + else + bound_l_x =3D (int16_t) col - ((int16_t)roi_xy_size / 32); + + bound_r_x =3D (int16_t) col + ((int16_t)roi_xy_size / 32); + + if ((((int16_t)roi_xy_size) & 0x01) =3D=3D 1) + bound_d_y =3D (int16_t) row - ((((int16_t)roi_xy_size & 0x0f) / 2) + 1); + else + bound_d_y =3D (int16_t) row - (((int16_t)roi_xy_size & 0x0f) / 2); + + bound_u_y =3D (int16_t) row + (((int16_t)roi_xy_size & 0xf) / 2); + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + bound_l_x =3D (2 * bound_l_x) - 15 + (2 * (int16_t)centre_offset_x); + bound_r_x =3D (2 * bound_r_x) - 15 + (2 * (int16_t)centre_offset_x); + bound_u_y =3D (2 * bound_u_y) - 15 + (2 * (int16_t)centre_offset_y); + bound_d_y =3D (2 * bound_d_y) - 15 + (2 * (int16_t)centre_offset_y); + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + xtalk_rate_ll =3D ((int64_t)bound_l_x * ((int64_t)xgradient)) + ((int64= _t)bound_d_y * ((int64_t)ygradient)); + xtalk_rate_ll =3D do_division_s((xtalk_rate_ll + 1), 2); + xtalk_rate_ll +=3D ((int64_t)mean_offset * 4); + + xtalk_rate_ur =3D ((int64_t)bound_r_x * ((int64_t)xgradient)) + ((int64= _t)bound_u_y * ((int64_t)ygradient)); + xtalk_rate_ur =3D do_division_s((xtalk_rate_ur + 1), 2); + xtalk_rate_ur +=3D ((int64_t)mean_offset * 4); + } + + if (status =3D=3D VL53LX_ERROR_NONE) + xtalk_avg =3D do_division_s(((xtalk_rate_ll + xtalk_rate_ur) + 1), 2); + + if (status =3D=3D VL53LX_ERROR_NONE) + if (xtalk_avg < 0) + xtalk_avg =3D 0; + + *xtalk_rate_kcps =3D (uint32_t) xtalk_avg; + return status; +} + +VL53LX_Error VL53LX_f_033(VL53LX_histogram_bin_data_t *phist_data, VL53LX_= xtalk_histogram_shape_t *pxtalk_data, uint32_t xtalk_rate_kcps, VL53LX_hist= ogram_bin_data_t *pxtalkcount_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + uint64_t xtalk_events_per_spad =3D 0; + uint64_t xtalk_total_events =3D 0; + uint64_t xtalk_temp_bin =3D 0; + uint8_t i =3D 0; + + xtalk_events_per_spad =3D do_division_u((((uint64_t)xtalk_rate_kcps * (ui= nt64_t)phist_data->peak_duration_us) + 500), 1000); + + xtalk_total_events =3D xtalk_events_per_spad * (uint64_t)phist_data->resu= lt__dss_actual_effective_spads; + xtalk_total_events =3D do_division_u((xtalk_total_events), 256); + xtalk_total_events =3D do_division_u((xtalk_total_events + 1024), 2048); + + if (xtalk_total_events > 0xFFFFFFFF) + xtalk_total_events =3D 0xFFFFFFFF; + + for (i =3D 0; i < pxtalk_data->VL53LX_p_021; i++) { + xtalk_temp_bin =3D (uint64_t)pxtalk_data->bin_data[i] * (uint64_t)xtalk_= total_events; + xtalk_temp_bin =3D do_division_u((xtalk_temp_bin + 512), 1024); + pxtalkcount_data->bin_data[i] =3D (uint32_t)xtalk_temp_bin; + } + return status; +} + +void VL53LX_copy_xtalk_bin_data_to_histogram_data_struct(VL53LX_xtalk_hist= ogram_shape_t *pxtalk, VL53LX_histogram_bin_data_t *phist) +{ + phist->cal_config__vcsel_start =3D pxtalk->cal_config__vcsel_start; + phist->VL53LX_p_015 =3D pxtalk->VL53LX_p_015; + phist->VL53LX_p_019 =3D pxtalk->VL53LX_p_019; + + phist->phasecal_result__reference_phase =3D pxtalk->phasecal_result__refe= rence_phase; + phist->phasecal_result__vcsel_start =3D pxtalk->phasecal_result__vcsel_st= art; + + phist->vcsel_width =3D pxtalk->vcsel_width; + phist->zero_distance_phase =3D pxtalk->zero_distance_phase; + + phist->zone_id =3D pxtalk->zone_id; + phist->VL53LX_p_020 =3D pxtalk->VL53LX_p_020; + phist->time_stamp =3D pxtalk->time_stamp; +} + +void VL53LX_f_003(VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + uint8_t lb =3D 0; + palgo->VL53LX_p_020 =3D VL53LX_HISTOGRAM_BUFFER_SIZE; + palgo->VL53LX_p_019 =3D 0; + palgo->VL53LX_p_021 =3D 0; + palgo->VL53LX_p_039 =3D 0; + palgo->VL53LX_p_028 =3D 0; + palgo->VL53LX_p_031 =3D 0; + + for (lb =3D palgo->VL53LX_p_019; lb < palgo->VL53LX_p_020; lb++) { + palgo->VL53LX_p_040[lb] =3D 0; + palgo->VL53LX_p_041[lb] =3D 0; + palgo->VL53LX_p_042[lb] =3D 0; + palgo->VL53LX_p_043[lb] =3D 0; + palgo->VL53LX_p_018[lb] =3D 0; + } + palgo->VL53LX_p_044 =3D 0; + palgo->VL53LX_p_045 =3D VL53LX_D_001; + palgo->VL53LX_p_046 =3D 0; + + VL53LX_init_histogram_bin_data_struct(0, VL53LX_HISTOGRAM_BUFFER_SIZE, &(= palgo->VL53LX_p_006)); + VL53LX_init_histogram_bin_data_struct(0, VL53LX_HISTOGRAM_BUFFER_SIZE, &(= palgo->VL53LX_p_047)); + VL53LX_init_histogram_bin_data_struct(0, VL53LX_HISTOGRAM_BUFFER_SIZE, &(= palgo->VL53LX_p_048)); + VL53LX_init_histogram_bin_data_struct(0, VL53LX_HISTOGRAM_BUFFER_SIZE, &(= palgo->VL53LX_p_049)); + VL53LX_init_histogram_bin_data_struct(0, VL53LX_HISTOGRAM_BUFFER_SIZE, &(= palgo->VL53LX_p_050)); +} + +void VL53LX_hist_find_min_max_bin_values(VL53LX_histogram_bin_data_t *pdat= a) +{ + uint8_t bin =3D 0; + + for (bin =3D 0; bin < pdata->VL53LX_p_021; bin++) { + if (bin =3D=3D 0 || pdata->min_bin_value >=3D pdata->bin_data[bin]) + pdata->min_bin_value =3D pdata->bin_data[bin]; + + if (bin =3D=3D 0 || pdata->max_bin_value <=3D pdata->bin_data[bin]) + pdata->max_bin_value =3D pdata->bin_data[bin]; + } +} + +uint32_t VL53LX_isqrt(uint32_t num) +{ + uint32_t res =3D 0; + uint32_t bit =3D 1 << 30; + + while (bit > num) + bit >>=3D 2; + + while (bit !=3D 0) { + if (num >=3D res + bit) { + num -=3D res + bit; + res =3D (res >> 1) + bit; + } else { + res >>=3D 1; + } + bit >>=3D 2; + } + + return res; +} + + +void VL53LX_hist_estimate_ambient_from_thresholded_bins(int32_t ambient_th= reshold_sigma, VL53LX_histogram_bin_data_t *pdata) +{ + uint8_t bin =3D 0; + int32_t VL53LX_p_031 =3D 0; + + VL53LX_hist_find_min_max_bin_values(pdata); + + VL53LX_p_031 =3D (int32_t)VL53LX_isqrt((uint32_t)pdata->min_bin_value); + VL53LX_p_031 *=3D ambient_threshold_sigma; + VL53LX_p_031 +=3D 0x07; + VL53LX_p_031 =3D VL53LX_p_031 >> 4; + VL53LX_p_031 +=3D pdata->min_bin_value; + + pdata->number_of_ambient_samples =3D 0; + pdata->ambient_events_sum =3D 0; + + for (bin =3D 0; bin < pdata->VL53LX_p_021; bin++) { + if (pdata->bin_data[bin] < VL53LX_p_031) { + pdata->ambient_events_sum +=3D pdata->bin_data[bin]; + pdata->number_of_ambient_samples++; + } + } + + if (pdata->number_of_ambient_samples > 0) { + pdata->VL53LX_p_028 =3D pdata->ambient_events_sum; + pdata->VL53LX_p_028 +=3D ((int32_t)pdata->number_of_ambient_samples/2); + pdata->VL53LX_p_028 /=3D (int32_t)pdata->number_of_ambient_samples; + } +} + +void VL53LX_hist_remove_ambient_bins(VL53LX_histogram_bin_data_t *pdata) +{ + uint8_t bin =3D 0; + uint8_t lc =3D 0; + uint8_t i =3D 0; + + if ((pdata->bin_seq[0] & 0x07) =3D=3D 0x07) { + i =3D 0; + for (lc =3D 0; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH; lc++) { + if ((pdata->bin_seq[lc] & 0x07) !=3D 0x07) { + pdata->bin_seq[i] =3D pdata->bin_seq[lc]; + pdata->bin_rep[i] =3D pdata->bin_rep[lc]; + i++; + } + } + for (lc =3D i; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH; lc++) { + pdata->bin_seq[lc] =3D VL53LX_MAX_BIN_SEQUENCE_CODE + 1; + pdata->bin_rep[lc] =3D 0; + } + } + if (pdata->number_of_ambient_bins > 0) { + for (bin =3D pdata->number_of_ambient_bins; bin < pdata->VL53LX_p_020; b= in++) { + pdata->bin_data[bin-pdata->number_of_ambient_bins] =3D pdata->bin_data[= bin]; + } + pdata->VL53LX_p_021 =3D pdata->VL53LX_p_021 - pdata->number_of_ambient_b= ins; + pdata->number_of_ambient_bins =3D 0; + } +} + +int8_t VL53LX_f_030(VL53LX_histogram_bin_data_t *pdata1, VL53LX_histogram_= bin_data_t *pdata2) +{ + int32_t phase_delta =3D 0; + int8_t bin_offset =3D 0; + uint32_t period =3D 0; + uint32_t remapped_phase =3D 0; + + period =3D 2048 * (uint32_t)VL53LX_decode_vcsel_period(pdata1->VL53LX_p_0= 05); + + if (period !=3D 0) + remapped_phase =3D (uint32_t)pdata2->zero_distance_phase % period; + + phase_delta =3D (int32_t)pdata1->zero_distance_phase - (int32_t)remapped_= phase; + + if (phase_delta > 0) + bin_offset =3D (int8_t)((phase_delta + 1024) / 2048); + else + bin_offset =3D (int8_t)((phase_delta - 1024) / 2048); + + return bin_offset; +} + +void VL53LX_f_005(VL53LX_histogram_bin_data_t *pxtalk, VL53LX_histogram_bi= n_data_t *pbins, VL53LX_histogram_bin_data_t *pxtalk_realigned) +{ + uint8_t i =3D 0; + uint8_t min_bins =3D 0; + int8_t bin_offset =3D 0; + int8_t bin_access =3D 0; + + memcpy(pxtalk_realigned, pbins, sizeof(VL53LX_histogram_bin_data_t)); + + for (i =3D 0 ; i < pxtalk_realigned->VL53LX_p_020 ; i++) + pxtalk_realigned->bin_data[i] =3D 0; + + bin_offset =3D VL53LX_f_030(pbins, pxtalk); + + if (pxtalk->VL53LX_p_021 < pbins->VL53LX_p_021) + min_bins =3D pxtalk->VL53LX_p_021; + else + min_bins =3D pbins->VL53LX_p_021; + + for (i =3D 0 ; i < min_bins ; i++) { + if (bin_offset >=3D 0) + bin_access =3D ((int8_t)i + (int8_t)bin_offset) % (int8_t)pbins->VL53LX= _p_021; + else + bin_access =3D ((int8_t)pbins->VL53LX_p_021 + ((int8_t)i + (int8_t)bin_= offset)) % (int8_t)pbins->VL53LX_p_021; + + if (pbins->bin_data[(uint8_t)bin_access] > pxtalk->bin_data[i]) { + pbins->bin_data[(uint8_t)bin_access] =3D pbins->bin_data[(uint8_t)bin_a= ccess] - pxtalk->bin_data[i]; + } else { + pbins->bin_data[(uint8_t)bin_access] =3D 0; + } + pxtalk_realigned->bin_data[(uint8_t)bin_access] =3D pxtalk->bin_data[i]; + + + + } +} + +uint16_t VL53LX_rate_maths(int32_t VL53LX_p_018, uint32_t time_us) +{ + uint32_t tmp_int =3D 0; + uint32_t frac_bits =3D 7; + uint16_t rate_mcps =3D 0; + + if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_MAX) + tmp_int =3D VL53LX_SPAD_TOTAL_COUNT_MAX; + else if (VL53LX_p_018 > 0) + tmp_int =3D (uint32_t)VL53LX_p_018; + + if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_RES_THRES) + frac_bits =3D 3; + else + frac_bits =3D 7; + + if (time_us > 0) + tmp_int =3D ((tmp_int << frac_bits) + (time_us / 2)) / time_us; + + if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_RES_THRES) + tmp_int =3D tmp_int << 4; + + if (tmp_int > 0xFFFF) + tmp_int =3D 0xFFFF; + + rate_mcps =3D (uint16_t)tmp_int; + return rate_mcps; +} + +uint32_t VL53LX_events_per_spad_maths(int32_t VL53LX_p_010, uint16_t num_s= pads, uint32_t duration) +{ + uint64_t total_hist_counts =3D 0; + uint64_t xtalk_per_spad =3D 0; + uint32_t rate_per_spad_kcps =3D 0; + uint64_t dividend =3D ((uint64_t)VL53LX_p_010 * 1000 * 256); + + if (num_spads !=3D 0) + total_hist_counts =3D do_division_u(dividend, (uint64_t)num_spads); + + if (duration > 0) { + uint64_t dividend =3D (((uint64_t)(total_hist_counts << 11)) + ((uint64_= t)duration / 2)); + xtalk_per_spad =3D do_division_u(dividend, (uint64_t)duration); + } else { + xtalk_per_spad =3D (uint64_t)(total_hist_counts << 11); + } + rate_per_spad_kcps =3D (uint32_t)xtalk_per_spad; + return rate_per_spad_kcps; +} + +uint32_t VL53LX_f_002(uint32_t events_threshold, uint32_t ref_signal_event= s, uint32_t ref_distance_mm, uint32_t signal_thresh_sigma) +{ + uint32_t tmp32 =3D 0; + uint32_t range_mm =3D 0; + + tmp32 =3D 4 * events_threshold; + tmp32 +=3D ((uint32_t)signal_thresh_sigma * (uint32_t)signal_thresh_sigma= ); + tmp32 =3D VL53LX_isqrt(tmp32); + tmp32 +=3D (uint32_t)signal_thresh_sigma; + + range_mm =3D (uint32_t)VL53LX_isqrt(ref_signal_events << 4); + range_mm *=3D ref_distance_mm; + if (tmp32 !=3D 0) { + range_mm +=3D (tmp32); + range_mm /=3D (2*tmp32); + } + return range_mm; +} + +VL53LX_Error VL53LX_f_001( + uint16_t target_reflectance, + VL53LX_dmax_calibration_data_t *pcal, + VL53LX_hist_gen3_dmax_config_t *pcfg, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_gen3_dmax_private_data_t *pdata, + int16_t *pambient_dmax_mm) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint32_t pll_period_us =3D 0; + uint32_t periods_elapsed =3D 0; + uint32_t tmp32 =3D 0; + uint64_t tmp64 =3D 0; + uint32_t amb_thres_delta =3D 0; + + pdata->VL53LX_p_004 =3D 0x0000; + pdata->VL53LX_p_033 =3D 0x0000; + pdata->VL53LX_p_034 =3D 0x0000; + pdata->VL53LX_p_009 =3D 0x0000; + pdata->VL53LX_p_028 =3D 0x0000; + pdata->VL53LX_p_035 =3D 0x0000; + pdata->VL53LX_p_036 =3D 0; + pdata->VL53LX_p_022 =3D 0; + *pambient_dmax_mm =3D 0; + + if ((pbins->VL53LX_p_015 !=3D 0) && (pbins->total_periods_elapsed !=3D 0)= ) { + pll_period_us =3D VL53LX_calc_pll_period_us(pbins->VL53LX_p_015); + periods_elapsed =3D pbins->total_periods_elapsed + 1; + pdata->VL53LX_p_037 =3D VL53LX_duration_maths(pll_period_us, 1<<4, VL53L= X_RANGING_WINDOW_VCSEL_PERIODS, periods_elapsed); + pdata->VL53LX_p_034 =3D VL53LX_rate_maths(pbins->VL53LX_p_028, pdata->VL= 53LX_p_037); + pdata->VL53LX_p_033 =3D VL53LX_events_per_spad_maths(pbins->VL53LX_p_028= , pbins->result__dss_actual_effective_spads, pdata->VL53LX_p_037); + pdata->VL53LX_p_038 =3D pcfg->max_effective_spads; + pdata->VL53LX_p_004 =3D pcfg->max_effective_spads; + + if (pdata->VL53LX_p_033 > 0) { + tmp64 =3D (uint64_t)pcfg->dss_config__target_total_rate_mcps; + tmp64 *=3D 1000; + tmp64 <<=3D (11+1); + tmp32 =3D pdata->VL53LX_p_033/2; + tmp64 +=3D (uint64_t)tmp32; + tmp64 =3D do_division_u(tmp64, (uint64_t)pdata->VL53LX_p_033); + if (tmp64 < (uint64_t)pcfg->max_effective_spads) + pdata->VL53LX_p_004 =3D (uint16_t)tmp64; + } + } + if ((pcal->ref__actual_effective_spads !=3D 0) && (pbins->VL53LX_p_015 != =3D 0) && (pcal->ref_reflectance_pc !=3D 0) && (pbins->total_periods_elapse= d !=3D 0)) { + tmp64 =3D (uint64_t)pcal->ref__peak_signal_count_rate_mcps; + tmp64 *=3D (1000 * 256); + tmp32 =3D pcal->ref__actual_effective_spads/2; + tmp64 +=3D (uint64_t)tmp32; + tmp64 =3D do_division_u(tmp64, (uint64_t)pcal->ref__actual_effective_sp= ads); + + pdata->VL53LX_p_009 =3D (uint32_t)tmp64; + pdata->VL53LX_p_009 <<=3D 4; + + tmp64 =3D (uint64_t)pdata->VL53LX_p_037; + tmp64 *=3D (uint64_t)pdata->VL53LX_p_033; + tmp64 *=3D (uint64_t)pdata->VL53LX_p_004; + tmp64 +=3D (1<<(11+7)); + tmp64 >>=3D (11+8); + tmp64 +=3D 500; + tmp64 =3D do_division_u(tmp64, 1000); + + if (tmp64 > 0x00FFFFFF) + tmp64 =3D 0x00FFFFFF; + + pdata->VL53LX_p_028 =3D (uint32_t)tmp64; + tmp64 =3D (uint64_t)pdata->VL53LX_p_037; + tmp64 *=3D (uint64_t)pdata->VL53LX_p_009; + tmp64 *=3D (uint64_t)pdata->VL53LX_p_004; + tmp64 +=3D (1<<(11+7)); + tmp64 >>=3D (11+8); + tmp64 *=3D ((uint64_t)target_reflectance * (uint64_t)pcal->coverglass_t= ransmission); + tmp64 +=3D ((uint64_t)pcal->ref_reflectance_pc * 128); + tmp64 =3D do_division_u(tmp64, ((uint64_t)pcal->ref_reflectance_pc * 25= 6)); + tmp64 +=3D 500; + tmp64 =3D do_division_u(tmp64, 1000); + if (tmp64 > 0x00FFFFFF) + tmp64 =3D 0x00FFFFFF; + pdata->VL53LX_p_035 =3D (uint32_t)tmp64; + tmp32 =3D VL53LX_isqrt(pdata->VL53LX_p_028 << 8); + tmp32 *=3D (uint32_t)pcfg->ambient_thresh_sigma; + if (pdata->VL53LX_p_028 < (uint32_t)pcfg->min_ambient_thresh_events) { + amb_thres_delta =3D pcfg->min_ambient_thresh_events - (uint32_t)pdata->= VL53LX_p_028; + amb_thres_delta <<=3D 8; + if (tmp32 < amb_thres_delta) + tmp32 =3D amb_thres_delta; + } + pdata->VL53LX_p_022 =3D (int16_t)VL53LX_f_002(tmp32, pdata->VL53LX_p_035= , (uint32_t)pcal->ref__distance_mm, (uint32_t)pcfg->signal_thresh_sigma); + + tmp32 =3D (uint32_t)pdata->VL53LX_p_035; + tmp32 *=3D (uint32_t)pbins->vcsel_width; + tmp32 +=3D (1 << 3); + tmp32 /=3D (1 << 4); + + pdata->VL53LX_p_036 =3D (int16_t)VL53LX_f_002(256 * (uint32_t)pcfg->sign= al_total_events_limit, tmp32, (uint32_t)pcal->ref__distance_mm, (uint32_t)p= cfg->signal_thresh_sigma); + + if (pdata->VL53LX_p_036 < pdata->VL53LX_p_022) + *pambient_dmax_mm =3D pdata->VL53LX_p_036; + else + *pambient_dmax_mm =3D pdata->VL53LX_p_022; + } + return status; +} + +VL53LX_Error VL53LX_f_006( + uint16_t ambient_threshold_events_scaler, + int32_t ambient_threshold_sigma, + int32_t min_ambient_threshold_events, + uint8_t algo__crosstalk_compensation_enable, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_histogram_bin_data_t *pxtalk, + VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t lb =3D 0; + uint8_t VL53LX_p_001 =3D 0; + int64_t tmp =3D 0; + int32_t amb_events =3D 0; + int32_t VL53LX_p_018 =3D 0; + int32_t samples =3D 0; + + palgo->VL53LX_p_020 =3D pbins->VL53LX_p_020; + palgo->VL53LX_p_019 =3D pbins->VL53LX_p_019; + palgo->VL53LX_p_021 =3D pbins->VL53LX_p_021; + palgo->VL53LX_p_028 =3D pbins->VL53LX_p_028; + palgo->VL53LX_p_030 =3D VL53LX_decode_vcsel_period(pbins->VL53LX_p_005); + + tmp =3D (int64_t)pbins->VL53LX_p_028; + tmp *=3D (int64_t)ambient_threshold_events_scaler; + tmp +=3D 2048; + tmp =3D do_division_s(tmp, 4096); + amb_events =3D (int32_t)tmp; + + for (lb =3D 0; lb < pbins->VL53LX_p_021; lb++) { + VL53LX_p_001 =3D lb >> 2; + samples =3D (int32_t)pbins->bin_rep[VL53LX_p_001]; + if (samples > 0) { + if (lb < pxtalk->VL53LX_p_021 && algo__crosstalk_compensation_enable > = 0) + VL53LX_p_018 =3D samples * (amb_events + pxtalk->bin_data[lb]); + else + VL53LX_p_018 =3D samples * amb_events; + VL53LX_p_018 =3D VL53LX_isqrt(VL53LX_p_018); + VL53LX_p_018 +=3D (samples/2); + VL53LX_p_018 /=3D samples; + VL53LX_p_018 *=3D ambient_threshold_sigma; + VL53LX_p_018 +=3D 8; + VL53LX_p_018 /=3D 16; + VL53LX_p_018 +=3D amb_events; + if (VL53LX_p_018 < min_ambient_threshold_events) + VL53LX_p_018 =3D min_ambient_threshold_events; + palgo->VL53LX_p_052[lb] =3D VL53LX_p_018; + palgo->VL53LX_p_031 =3D VL53LX_p_018; + } + } + palgo->VL53LX_p_039 =3D 0; + for (lb =3D pbins->VL53LX_p_019; lb < pbins->VL53LX_p_021; lb++) { + if (pbins->bin_data[lb] > palgo->VL53LX_p_052[lb]) { + palgo->VL53LX_p_040[lb] =3D 1; + palgo->VL53LX_p_041[lb] =3D 1; + palgo->VL53LX_p_039++; + } else { + palgo->VL53LX_p_040[lb] =3D 0; + palgo->VL53LX_p_041[lb] =3D 0; + } + } + return status; +} + +VL53LX_Error VL53LX_f_007(VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t i =3D 0; + uint8_t j =3D 0; + uint8_t found =3D 0; + + palgo->VL53LX_p_044 =3D 0; + for (i =3D 0; i < palgo->VL53LX_p_030; i++) { + j =3D (i + 1) % palgo->VL53LX_p_030; + if (i < palgo->VL53LX_p_021 && j < palgo->VL53LX_p_021) { + if (palgo->VL53LX_p_041[i] =3D=3D 0 && palgo->VL53LX_p_041[j] =3D=3D 1 = && found =3D=3D 0) { + palgo->VL53LX_p_044 =3D i; + found =3D 1; + } + } + } + return status; +} + +VL53LX_Error VL53LX_f_008(VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t i =3D 0; + uint8_t j =3D 0; + uint8_t lb =3D 0; + + for (lb =3D palgo->VL53LX_p_044; lb < (palgo->VL53LX_p_044 + palgo->VL53L= X_p_030); lb++) { + i =3D lb % palgo->VL53LX_p_030; + j =3D (lb + 1) % palgo->VL53LX_p_030; + if (i < palgo->VL53LX_p_021 && j < palgo->VL53LX_p_021) { + if (palgo->VL53LX_p_041[i] =3D=3D 0 && palgo->VL53LX_p_041[j] =3D=3D 1) + palgo->VL53LX_p_046++; + if (palgo->VL53LX_p_046 > palgo->VL53LX_p_045) + palgo->VL53LX_p_046 =3D palgo->VL53LX_p_045; + if (palgo->VL53LX_p_041[i] > 0) + palgo->VL53LX_p_042[i] =3D palgo->VL53LX_p_046; + else + palgo->VL53LX_p_042[i] =3D 0; + } + } + return status; +} + +VL53LX_Error VL53LX_f_009(VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + uint8_t i =3D 0; + uint8_t j =3D 0; + uint8_t blb =3D 0; + uint8_t pulse_no =3D 0; + uint8_t max_filter_half_width =3D 0; + VL53LX_hist_pulse_data_t *pdata; + + max_filter_half_width =3D palgo->VL53LX_p_030 - 1; + max_filter_half_width =3D max_filter_half_width >> 1; + + for (blb =3D palgo->VL53LX_p_044; blb < (palgo->VL53LX_p_044 + palgo->VL5= 3LX_p_030); blb++) { + i =3D blb % palgo->VL53LX_p_030; + j =3D (blb + 1) % palgo->VL53LX_p_030; + + if (i < palgo->VL53LX_p_021 && j < palgo->VL53LX_p_021) { + if (palgo->VL53LX_p_042[i] =3D=3D 0 && palgo->VL53LX_p_042[j] > 0) { + pulse_no =3D palgo->VL53LX_p_042[j] - 1; + if (pulse_no < palgo->VL53LX_p_045) { + pdata =3D &(palgo->VL53LX_p_003[pulse_no]); + pdata->VL53LX_p_012 =3D blb; + pdata->VL53LX_p_019 =3D blb + 1; + pdata->VL53LX_p_023 =3D 0xFF; + pdata->VL53LX_p_024 =3D 0; + pdata->VL53LX_p_013 =3D 0; + } + } + if (palgo->VL53LX_p_042[i] > 0 && palgo->VL53LX_p_042[j] =3D=3D 0) { + pulse_no =3D palgo->VL53LX_p_042[i] - 1; + if (pulse_no < palgo->VL53LX_p_045) { + pdata =3D &(palgo->VL53LX_p_003[pulse_no]); + pdata->VL53LX_p_024 =3D blb; + pdata->VL53LX_p_013 =3D blb + 1; + pdata->VL53LX_p_025 =3D (pdata->VL53LX_p_024 + 1) - pdata->VL53LX_p_0= 19; + pdata->VL53LX_p_051 =3D (pdata->VL53LX_p_013 + 1) - pdata->VL53LX_p_0= 12; + if (pdata->VL53LX_p_051 > max_filter_half_width) + pdata->VL53LX_p_051 =3D max_filter_half_width; + } + } + } + } + return status; +} + +VL53LX_Error VL53LX_f_010(uint8_t pulse_no, VL53LX_histogram_bin_data_t *p= bins, VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t i =3D 0; + uint8_t lb =3D 0; + + VL53LX_hist_pulse_data_t *pdata =3D &(palgo->VL53LX_p_003[pulse_no]); + pdata->VL53LX_p_017 =3D 0; + pdata->VL53LX_p_016 =3D 0; + + for (lb =3D pdata->VL53LX_p_012; lb <=3D pdata->VL53LX_p_013; lb++) { + i =3D lb % palgo->VL53LX_p_030; + pdata->VL53LX_p_017 +=3D pbins->bin_data[i]; + pdata->VL53LX_p_016 +=3D palgo->VL53LX_p_028; + } + pdata->VL53LX_p_010 =3D pdata->VL53LX_p_017 - pdata->VL53LX_p_016; + return status; +} + +VL53LX_Error VL53LX_f_011( + uint8_t pulse_no, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_gen3_algo_private_data_t *palgo, + int32_t pad_value, + VL53LX_histogram_bin_data_t *ppulse) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + uint8_t i =3D 0; + uint8_t lb =3D 0; + VL53LX_hist_pulse_data_t *pdata =3D &(palgo->VL53LX_p_003[pulse_no]); + + memcpy(ppulse, pbins, sizeof(VL53LX_histogram_bin_data_t)); + + for (lb =3D palgo->VL53LX_p_044; lb < (palgo->VL53LX_p_044 + palgo->VL53L= X_p_030); lb++) { + if (lb < pdata->VL53LX_p_012 || lb > pdata->VL53LX_p_013) { + i =3D lb % palgo->VL53LX_p_030; + if (i < ppulse->VL53LX_p_021) + ppulse->bin_data[i] =3D pad_value; + } + } + return status; +} + +void VL53LX_f_022(uint8_t VL53LX_p_032, uint8_t filter_woi, VL53LX_histogr= am_bin_data_t *pbins, int32_t *pa, int32_t *pb, int32_t *pc) +{ + uint8_t w =3D 0; + uint8_t j =3D 0; + + *pa =3D 0; + *pb =3D pbins->bin_data[VL53LX_p_032]; + *pc =3D 0; + + for (w =3D 0 ; w < ((filter_woi << 1)+1) ; w++) { + j =3D ((VL53LX_p_032 + w + pbins->VL53LX_p_021) - filter_woi) % pbins->V= L53LX_p_021; + if (w < filter_woi) + *pa +=3D pbins->bin_data[j]; + else if (w > filter_woi) + *pc +=3D pbins->bin_data[j]; + } +} + +VL53LX_Error VL53LX_f_026( + uint8_t pulse_no, + VL53LX_histogram_bin_data_t *ppulse, + VL53LX_hist_gen3_algo_private_data_t *palgo3, + VL53LX_hist_gen4_algo_filtered_data_t *pfiltered) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_hist_pulse_data_t *pdata =3D &(palgo3->VL53LX_p_003[pulse_no]); + + uint8_t lb =3D 0; + uint8_t i =3D 0; + int32_t suma =3D 0; + int32_t sumb =3D 0; + int32_t sumc =3D 0; + + pfiltered->VL53LX_p_020 =3D palgo3->VL53LX_p_020; + pfiltered->VL53LX_p_019 =3D palgo3->VL53LX_p_019; + pfiltered->VL53LX_p_021 =3D palgo3->VL53LX_p_021; + + for (lb =3D pdata->VL53LX_p_012; lb <=3D pdata->VL53LX_p_013; lb++) { + i =3D lb % palgo3->VL53LX_p_030; + VL53LX_f_022(i, pdata->VL53LX_p_051, ppulse, &suma, &sumb, &sumc); + + pfiltered->VL53LX_p_007[i] =3D suma; + pfiltered->VL53LX_p_032[i] =3D sumb; + pfiltered->VL53LX_p_001[i] =3D sumc; + pfiltered->VL53LX_p_053[i] =3D (suma + sumb) - (sumc + palgo3->VL53LX_p_= 028); + pfiltered->VL53LX_p_054[i] =3D (sumb + sumc) - (suma + palgo3->VL53LX_p_= 028); + } + return status; +} + +VL53LX_Error VL53LX_f_028( + uint8_t bin, + int32_t VL53LX_p_007, + int32_t VL53LX_p_032, + int32_t VL53LX_p_001, + int32_t ax, + int32_t bx, + int32_t cx, + int32_t VL53LX_p_028, + uint8_t VL53LX_p_030, + uint32_t *pmean_phase) +{ + VL53LX_Error status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + + int64_t mean_phase =3D VL53LX_MAX_ALLOWED_PHASE; + int32_t mean_phase32; + int64_t VL53LX_p_055 =3D 0; + int64_t half_b_minus_amb =3D 0; + + VL53LX_p_055 =3D 4096 * ((int64_t)VL53LX_p_001 - (int64_t)cx - (int64= _t)VL53LX_p_007 - (int64_t)ax); + half_b_minus_amb =3D 4096 * ((int64_t)VL53LX_p_032 - (int64_t)bx - (int64= _t)VL53LX_p_028); + + if (half_b_minus_amb !=3D 0) { + mean_phase =3D (4096 * VL53LX_p_055) + half_b_minus_amb; + mean_phase =3D do_division_s(mean_phase, (half_b_minus_amb * 2)); + mean_phase +=3D 2048; + mean_phase +=3D (4096 * (int64_t)bin); + mean_phase =3D do_division_s((mean_phase + 1), 2); + if (mean_phase < 0) + mean_phase =3D 0; + if (mean_phase > VL53LX_MAX_ALLOWED_PHASE) + mean_phase =3D VL53LX_MAX_ALLOWED_PHASE; + mean_phase32 =3D (int32_t)mean_phase; + mean_phase32 =3D mean_phase32 % ((int32_t)VL53LX_p_030 * 2048); + mean_phase =3D mean_phase32; + status =3D VL53LX_ERROR_NONE; + } + *pmean_phase =3D (uint32_t)mean_phase; + return status; +} + +VL53LX_Error VL53LX_f_027(uint8_t pulse_no, uint16_t noise_threshold, VL53= LX_hist_gen4_algo_filtered_data_t *pfiltered, VL53LX_hist_gen3_algo_private= _data_t *palgo3) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_Error func_status =3D VL53LX_ERROR_NONE; + VL53LX_hist_pulse_data_t *pdata =3D &(palgo3->VL53LX_p_003[pulse_no]); + + uint8_t lb =3D 0; + uint8_t i =3D 0; + uint8_t j =3D 0; + + for (lb =3D pdata->VL53LX_p_012; lb < pdata->VL53LX_p_013; lb++) { + i =3D lb % palgo3->VL53LX_p_030; + j =3D (lb+1) % palgo3->VL53LX_p_030; + if (i < palgo3->VL53LX_p_021 && j < palgo3->VL53LX_p_021) { + if (pfiltered->VL53LX_p_053[i] =3D=3D 0 && pfiltered->VL53LX_p_054[i] = =3D=3D 0) + pfiltered->VL53LX_p_040[i] =3D 0; + else if (pfiltered->VL53LX_p_053[i] >=3D 0 && pfiltered->VL53LX_p_054[i= ] >=3D 0) + pfiltered->VL53LX_p_040[i] =3D 1; + else if (pfiltered->VL53LX_p_053[i] < 0 && pfiltered->VL53LX_p_054[i] = >=3D 0 && pfiltered->VL53LX_p_053[j] >=3D 0 && pfiltered->VL53LX_p_054[j] <= 0) + pfiltered->VL53LX_p_040[i] =3D 1; + else + pfiltered->VL53LX_p_040[i] =3D 0; + + if (pfiltered->VL53LX_p_040[i] > 0) { + pdata->VL53LX_p_023 =3D lb; + func_status =3D + VL53LX_f_028( + lb, + pfiltered->VL53LX_p_007[i], + pfiltered->VL53LX_p_032[i], + pfiltered->VL53LX_p_001[i], + 0, + 0, + 0, + palgo3->VL53LX_p_028, + palgo3->VL53LX_p_030, + &(pdata->VL53LX_p_011)); + + if (func_status =3D=3D + VL53LX_ERROR_DIVISION_BY_ZERO) + pfiltered->VL53LX_p_040[i] =3D 0; + + } + } + } + return status; +} + +uint32_t VL53LX_calc_pll_period_mm(uint16_t fast_osc_frequency) +{ + uint32_t pll_period_us =3D 0; + uint32_t pll_period_mm =3D 0; + + pll_period_us =3D VL53LX_calc_pll_period_us(fast_osc_frequency); + pll_period_mm =3D VL53LX_SPEED_OF_LIGHT_IN_AIR_DIV_8 * (pll_period_us >> = 2); + pll_period_mm =3D (pll_period_mm + (0x01<<15)) >> 16; + + return pll_period_mm; +} + +VL53LX_Error VL53LX_f_023( + uint8_t sigma_estimator__sigma_ref_mm, + uint32_t VL53LX_p_007, + uint32_t VL53LX_p_032, + uint32_t VL53LX_p_001, + uint32_t a_zp, + uint32_t c_zp, + uint32_t bx, + uint32_t ax_zp, + uint32_t cx_zp, + uint32_t VL53LX_p_028, + uint16_t fast_osc_frequency, + uint16_t *psigma_est) +{ + VL53LX_Error status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + uint32_t sigma_int =3D VL53LX_D_002; + uint32_t pll_period_mm =3D 0; + uint64_t tmp0 =3D 0; + uint64_t tmp1 =3D 0; + uint64_t b_minus_amb =3D 0; + uint64_t VL53LX_p_055 =3D 0; + *psigma_est =3D VL53LX_D_002; + if (fast_osc_frequency !=3D 0) { + pll_period_mm =3D VL53LX_calc_pll_period_mm(fast_osc_frequency); + + if (VL53LX_p_028 > VL53LX_p_032) + b_minus_amb =3D (uint64_t)VL53LX_p_028 - (uint64_t)VL53LX_p_032; + else + b_minus_amb =3D (uint64_t)VL53LX_p_032 - (uint64_t)VL53LX_p_028; + + if (VL53LX_p_007 > VL53LX_p_001) + VL53LX_p_055 =3D (uint64_t)VL53LX_p_007 - (uint64_t)VL53LX_p_001; + else + VL53LX_p_055 =3D (uint64_t)VL53LX_p_001 - (uint64_t)VL53LX_p_007; + + if (b_minus_amb !=3D 0) { + tmp0 =3D (uint64_t)VL53LX_p_032 + (uint64_t)bx + (uint64_t)VL53LX_p_028; + if (tmp0 > VL53LX_D_003) + tmp0 =3D VL53LX_D_003; + + tmp1 =3D (uint64_t)VL53LX_p_055 * (uint64_t)VL53LX_p_055; + tmp1 =3D tmp1 << 8; + + if (tmp1 > VL53LX_D_004) + tmp1 =3D VL53LX_D_004; + + tmp1 =3D do_division_u(tmp1, b_minus_amb); + tmp1 =3D do_division_u(tmp1, b_minus_amb); + + if (tmp1 > (uint64_t)VL53LX_D_005) + tmp1 =3D (uint64_t)VL53LX_D_005; + + tmp0 =3D tmp1 * tmp0; + tmp1 =3D (uint64_t)c_zp + (uint64_t)cx_zp + (uint64_t)a_zp + (uint64_t)= ax_zp; + + if (tmp1 > (uint64_t)VL53LX_D_003) + tmp1 =3D (uint64_t)VL53LX_D_003; + + tmp1 =3D tmp1 << 8; + + tmp0 =3D tmp1 + tmp0; + if (tmp0 > (uint64_t)VL53LX_D_006) + tmp0 =3D (uint64_t)VL53LX_D_006; + + if (tmp0 > (uint64_t)VL53LX_D_007) { + tmp0 =3D do_division_u(tmp0, b_minus_amb); + tmp0 =3D tmp0 * pll_period_mm; + } else { + tmp0 =3D tmp0 * pll_period_mm; + tmp0 =3D do_division_u(tmp0, b_minus_amb); + } + + if (tmp0 > (uint64_t)VL53LX_D_006) + tmp0 =3D (uint64_t)VL53LX_D_006; + + if (tmp0 > (uint64_t)VL53LX_D_007) { + tmp0 =3D do_division_u(tmp0, b_minus_amb); + tmp0 =3D do_division_u(tmp0, 4); + tmp0 =3D tmp0 * pll_period_mm; + } else { + tmp0 =3D tmp0 * pll_period_mm; + tmp0 =3D do_division_u(tmp0, b_minus_amb); + tmp0 =3D do_division_u(tmp0, 4); + } + + if (tmp0 > (uint64_t)VL53LX_D_006) + tmp0 =3D (uint64_t)VL53LX_D_006; + + tmp0 =3D tmp0 >> 2; + + if (tmp0 > (uint64_t)VL53LX_D_007) + tmp0 =3D (uint64_t)VL53LX_D_007; + + tmp1 =3D (uint64_t)sigma_estimator__sigma_ref_mm << 7; + tmp1 =3D tmp1 * tmp1; + tmp0 =3D tmp0 + tmp1; + + if (tmp0 > (uint64_t)VL53LX_D_007) + tmp0 =3D (uint64_t)VL53LX_D_007; + + sigma_int =3D VL53LX_isqrt((uint32_t)tmp0); + *psigma_est =3D (uint16_t)sigma_int; + status =3D VL53LX_ERROR_NONE; + } + } + return status; +} + +VL53LX_Error VL53LX_f_014( + uint8_t bin, + uint8_t sigma_estimator__sigma_ref_mm, + uint8_t VL53LX_p_030, + uint8_t VL53LX_p_051, + uint8_t crosstalk_compensation_enable, + VL53LX_histogram_bin_data_t *phist_data_ap, + VL53LX_histogram_bin_data_t *phist_data_zp, + VL53LX_histogram_bin_data_t *pxtalk_hist, + uint16_t *psigma_est) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_Error func_status =3D VL53LX_ERROR_NONE; + + uint8_t i =3D 0; + int32_t VL53LX_p_007 =3D 0; + int32_t VL53LX_p_032 =3D 0; + int32_t VL53LX_p_001 =3D 0; + int32_t a_zp =3D 0; + int32_t c_zp =3D 0; + int32_t ax =3D 0; + int32_t bx =3D 0; + int32_t cx =3D 0; + + if (VL53LX_p_030 =3D=3D 0) { + *psigma_est =3D 0xFFFF; + return VL53LX_ERROR_DIVISION_BY_ZERO; + } + i =3D bin % VL53LX_p_030; + + VL53LX_f_022(i, VL53LX_p_051, phist_data_zp, &a_zp, &VL53LX_p_032, &c_zp); + VL53LX_f_022(i, VL53LX_p_051, phist_data_ap, &VL53LX_p_007, &VL53LX_p_032= , &VL53LX_p_001); + + if (crosstalk_compensation_enable > 0) + VL53LX_f_022(i, VL53LX_p_051, pxtalk_hist, &ax, &bx, &cx); + + func_status =3D + VL53LX_f_023( + sigma_estimator__sigma_ref_mm, + (uint32_t)VL53LX_p_007, + (uint32_t)VL53LX_p_032, + (uint32_t)VL53LX_p_001, + (uint32_t)a_zp, + (uint32_t)c_zp, + (uint32_t)bx, + (uint32_t)ax, + (uint32_t)cx, + (uint32_t)phist_data_ap->VL53LX_p_028, + phist_data_ap->VL53LX_p_015, + psigma_est); + + if (func_status =3D=3D VL53LX_ERROR_DIVISION_BY_ZERO) + *psigma_est =3D 0xFFFF; + + return status; +} + +VL53LX_Error VL53LX_f_020(int16_t VL53LX_p_019, int16_t VL53LX_p_024, uint= 8_t VL53LX_p_030, uint8_t clip_events, VL53LX_histogram_bin_data_t *pbins, = uint32_t *pphase) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + int16_t i =3D 0; + int16_t lb =3D 0; + int64_t VL53LX_p_018 =3D 0; + int64_t event_sum =3D 0; + int64_t weighted_sum =3D 0; + + *pphase =3D VL53LX_MAX_ALLOWED_PHASE; + + if (VL53LX_p_030 !=3D 0) { + for (lb =3D VL53LX_p_019; lb <=3D VL53LX_p_024; lb++) { + if (lb < 0) + i =3D lb + (int16_t)VL53LX_p_030; + else + i =3D lb % (int16_t)VL53LX_p_030; + + if ((i >=3D 0) && (i < VL53LX_HISTOGRAM_BUFFER_SIZE)) { + VL53LX_p_018 =3D (int64_t)pbins->bin_data[i] - (int64_t)pbins->VL53LX_= p_028; + + if (clip_events > 0 && VL53LX_p_018 < 0) + VL53LX_p_018 =3D 0; + event_sum +=3D VL53LX_p_018; + weighted_sum +=3D (VL53LX_p_018 * (1024 + (2048*(int64_t)lb))); + } + + } + if (event_sum > 0) { + weighted_sum +=3D do_division_s(event_sum, 2); + weighted_sum =3D do_division_s(weighted_sum, event_sum); + if (weighted_sum < 0) + weighted_sum =3D 0; + *pphase =3D (uint32_t)weighted_sum; + } + } + return status; +} + +VL53LX_Error VL53LX_f_015(uint8_t pulse_no, uint8_t clip_events, VL53LX_hi= stogram_bin_data_t *pbins, VL53LX_hist_gen3_algo_private_data_t *palgo) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint8_t i =3D 0; + int16_t VL53LX_p_012 =3D 0; + int16_t VL53LX_p_013 =3D 0; + int16_t window_width =3D 0; + uint32_t tmp_phase =3D 0; + + VL53LX_hist_pulse_data_t *pdata =3D &(palgo->VL53LX_p_003[pulse_no]); + + if (pdata->VL53LX_p_023 =3D=3D 0xFF) + pdata->VL53LX_p_023 =3D 1; + + i =3D pdata->VL53LX_p_023 % palgo->VL53LX_p_030; + + VL53LX_p_012 =3D (int16_t)i; + VL53LX_p_012 +=3D (int16_t)pdata->VL53LX_p_012; + VL53LX_p_012 -=3D (int16_t)pdata->VL53LX_p_023; + + VL53LX_p_013 =3D (int16_t)i; + VL53LX_p_013 +=3D (int16_t)pdata->VL53LX_p_013; + VL53LX_p_013 -=3D (int16_t)pdata->VL53LX_p_023; + + window_width =3D VL53LX_p_013 - VL53LX_p_012; + if (window_width > 3) + window_width =3D 3; + + status =3D VL53LX_f_020(VL53LX_p_012, VL53LX_p_012 + window_width, palgo-= >VL53LX_p_030, clip_events, pbins, &(pdata->VL53LX_p_026)); + + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_020(VL53LX_p_013 - window_width, VL53LX_p_013, palgo= ->VL53LX_p_030, clip_events, pbins, &(pdata->VL53LX_p_027)); + + if (pdata->VL53LX_p_026 > pdata->VL53LX_p_027) { + tmp_phase =3D pdata->VL53LX_p_026; + pdata->VL53LX_p_026 =3D pdata->VL53LX_p_027; + pdata->VL53LX_p_027 =3D tmp_phase; + } + + if (pdata->VL53LX_p_011 < pdata->VL53LX_p_026) + pdata->VL53LX_p_026 =3D pdata->VL53LX_p_011; + + if (pdata->VL53LX_p_011 > pdata->VL53LX_p_027) + pdata->VL53LX_p_027 =3D pdata->VL53LX_p_011; + + return status; +} + +VL53LX_Error VL53LX_f_016(VL53LX_HistTargetOrder target_order, VL53LX_hist= _gen3_algo_private_data_t *palgo) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_hist_pulse_data_t tmp; + VL53LX_hist_pulse_data_t *ptmp =3D &tmp; + VL53LX_hist_pulse_data_t *p0; + VL53LX_hist_pulse_data_t *p1; + + uint8_t i =3D 0; + uint8_t swapped =3D 1; + + if (!(palgo->VL53LX_p_046 > 1)) + goto ENDFUNC; + + while (swapped > 0) { + swapped =3D 0; + for (i =3D 1; i < palgo->VL53LX_p_046; i++) { + p0 =3D &(palgo->VL53LX_p_003[i-1]); + p1 =3D &(palgo->VL53LX_p_003[i]); + + if (target_order =3D=3D VL53LX_HIST_TARGET_ORDER__STRONGEST_FIRST) { + if (p0->VL53LX_p_010 < p1->VL53LX_p_010) { + memcpy(ptmp, p1, sizeof(VL53LX_hist_pulse_data_t)); + memcpy(p1, p0, sizeof(VL53LX_hist_pulse_data_t)); + memcpy(p0, ptmp, sizeof(VL53LX_hist_pulse_data_t)); + swapped =3D 1; + } + } else { + if (p0->VL53LX_p_011 > p1->VL53LX_p_011) { + memcpy(ptmp, p1, sizeof(VL53LX_hist_pulse_data_t)); + memcpy(p1, p0, sizeof(VL53LX_hist_pulse_data_t)); + memcpy(p0, ptmp, sizeof(VL53LX_hist_pulse_data_t)); + swapped =3D 1; + } + } + } + } +ENDFUNC: + return status; + +} + +void VL53LX_f_017( + uint8_t range_id, + uint8_t valid_phase_low, + uint8_t valid_phase_high, + uint16_t sigma_thres, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_hist_pulse_data_t *ppulse, + VL53LX_range_data_t *pdata) +{ + uint16_t lower_phase_limit =3D 0; + uint16_t upper_phase_limit =3D 0; + + pdata->range_id =3D range_id; + pdata->time_stamp =3D 0; + pdata->VL53LX_p_012 =3D ppulse->VL53LX_p_012; + pdata->VL53LX_p_019 =3D ppulse->VL53LX_p_019; + pdata->VL53LX_p_023 =3D ppulse->VL53LX_p_023; + pdata->VL53LX_p_024 =3D ppulse->VL53LX_p_024; + pdata->VL53LX_p_013 =3D ppulse->VL53LX_p_013; + pdata->VL53LX_p_025 =3D ppulse->VL53LX_p_025; + pdata->VL53LX_p_029 =3D (ppulse->VL53LX_p_013 + 1) - ppulse->VL53LX_p_012; + + pdata->zero_distance_phase =3D pbins->zero_distance_phase; + pdata->VL53LX_p_002 =3D ppulse->VL53LX_p_002; + pdata->VL53LX_p_026 =3D (uint16_t)ppulse->VL53LX_p_026; + pdata->VL53LX_p_011 =3D (uint16_t)ppulse->VL53LX_p_011; + pdata->VL53LX_p_027 =3D (uint16_t)ppulse->VL53LX_p_027; + pdata->VL53LX_p_017 =3D (uint32_t)ppulse->VL53LX_p_017; + pdata->VL53LX_p_010 =3D ppulse->VL53LX_p_010; + pdata->VL53LX_p_016 =3D (uint32_t)ppulse->VL53LX_p_016; + pdata->total_periods_elapsed =3D pbins->total_periods_elapsed; + + pdata->range_status =3D VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK; + + if (sigma_thres > 0 && (uint32_t)ppulse->VL53LX_p_002 > ((uint32_t)sigma_= thres << 5)) + pdata->range_status =3D VL53LX_DEVICEERROR_SIGMATHRESHOLDCHECK; + + lower_phase_limit =3D (uint8_t)valid_phase_low << 8; + if (lower_phase_limit < pdata->zero_distance_phase) + lower_phase_limit =3D pdata->zero_distance_phase - lower_phase_limit; + else + lower_phase_limit =3D 0; + + upper_phase_limit =3D (uint8_t)valid_phase_high << 8; + upper_phase_limit +=3D pbins->zero_distance_phase; + + if (pdata->VL53LX_p_011 < lower_phase_limit || + pdata->VL53LX_p_011 > upper_phase_limit) + pdata->range_status =3D VL53LX_DEVICEERROR_RANGEPHASECHECK; +} + +int32_t VL53LX_range_maths( + uint16_t fast_osc_frequency, + uint16_t VL53LX_p_014, + uint16_t zero_distance_phase, + uint8_t fractional_bits, + int32_t gain_factor, + int32_t range_offset_mm) +{ + uint32_t pll_period_us =3D 0; + int64_t tmp_long_int =3D 0; + int32_t range_mm =3D 0; + int32_t range_mm_10 =3D 0; + + pll_period_us =3D VL53LX_calc_pll_period_us(fast_osc_frequency); + + tmp_long_int =3D (int64_t)VL53LX_p_014 - (int64_t)zero_distance_phase; + tmp_long_int =3D tmp_long_int * (int64_t)pll_period_us; + tmp_long_int =3D tmp_long_int / (0x01 << 9); + tmp_long_int =3D tmp_long_int * VL53LX_SPEED_OF_LIGHT_IN_AIR_DIV_8; + tmp_long_int =3D tmp_long_int / (0x01 << 22); + + range_mm =3D (int32_t)tmp_long_int + range_offset_mm; + range_mm *=3D gain_factor; + range_mm +=3D 0x0400; + range_mm /=3D 0x0800; + + if (fractional_bits =3D=3D 0) { + range_mm_10 =3D range_mm * 10; + range_mm_10 =3D range_mm_10 / (0x01 << 2); + if ((range_mm_10 % 10) < 5) + range_mm =3D (int16_t)(range_mm_10 / 10); + else + range_mm =3D (int16_t)(range_mm_10 / 10 + 1); + } else if (fractional_bits =3D=3D 1) + range_mm =3D range_mm / (0x01 << 1); + return range_mm; +} + +void VL53LX_f_019(uint16_t gain_factor, int16_t range_offset_mm, VL53LX_ra= nge_data_t *pdata) +{ + pdata->min_range_mm =3D + (int16_t)VL53LX_range_maths( + pdata->fast_osc_frequency, + pdata->VL53LX_p_026, + pdata->zero_distance_phase, + 0, + (int32_t)gain_factor, + (int32_t)range_offset_mm); + + pdata->median_range_mm =3D + (int16_t)VL53LX_range_maths( + pdata->fast_osc_frequency, + pdata->VL53LX_p_011, + pdata->zero_distance_phase, + 0, + (int32_t)gain_factor, + (int32_t)range_offset_mm); + + pdata->max_range_mm =3D + (int16_t)VL53LX_range_maths( + pdata->fast_osc_frequency, + pdata->VL53LX_p_027, + pdata->zero_distance_phase, + 0, + (int32_t)gain_factor, + (int32_t)range_offset_mm); +} + +uint16_t VL53LX_rate_per_spad_maths(uint32_t frac_bits, uint32_t peak_coun= t_rate, uint16_t num_spads, uint32_t max_output_value) +{ + uint32_t tmp_int =3D 0; + uint16_t rate_per_spad =3D 0; + + if (num_spads > 0) { + tmp_int =3D (peak_count_rate << 8) << frac_bits; + tmp_int =3D (tmp_int + ((uint32_t)num_spads / 2)) / (uint32_t)num_spads; + } else { + tmp_int =3D ((peak_count_rate) << frac_bits); + } + + if (tmp_int > max_output_value) + tmp_int =3D max_output_value; + + rate_per_spad =3D (uint16_t)tmp_int; + + return rate_per_spad; +} + +VL53LX_Error VL53LX_f_018( + uint16_t vcsel_width, + uint16_t fast_osc_frequency, + uint32_t total_periods_elapsed, + uint16_t VL53LX_p_004, + VL53LX_range_data_t *pdata, + uint8_t histo_merge_nb) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + uint32_t pll_period_us =3D 0; + uint32_t periods_elapsed =3D 0; + uint32_t count_rate_total =3D 0; + + pdata->width =3D vcsel_width; + pdata->fast_osc_frequency =3D fast_osc_frequency; + pdata->total_periods_elapsed =3D total_periods_elapsed; + pdata->VL53LX_p_004 =3D VL53LX_p_004; + + if (pdata->fast_osc_frequency =3D=3D 0) + status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + + if (pdata->total_periods_elapsed =3D=3D 0) + status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + + if (status =3D=3D VL53LX_ERROR_NONE) { + pll_period_us =3D VL53LX_calc_pll_period_us(pdata->fast_osc_frequency); + + periods_elapsed =3D pdata->total_periods_elapsed + 1; + + pdata->peak_duration_us =3D VL53LX_duration_maths(pll_period_us, (uin= t32_t)pdata->width, VL53LX_RANGING_WINDOW_VCSEL_PERIODS, periods_elapsed); + + pdata->woi_duration_us =3D VL53LX_duration_maths(pll_period_us, ((ui= nt32_t)pdata->VL53LX_p_029) << 4, VL53LX_RANGING_WINDOW_VCSEL_PERIODS, peri= ods_elapsed); + + pdata->peak_signal_count_rate_mcps =3D VL53LX_rate_maths((int32_t)pdata-= >VL53LX_p_010, pdata->peak_duration_us); + + pdata->avg_signal_count_rate_mcps =3D VL53LX_rate_maths((int32_t)pdata->= VL53LX_p_010, pdata->woi_duration_us); + + pdata->ambient_count_rate_mcps =3D VL53LX_rate_maths((int32_t)pdata->= VL53LX_p_016, pdata->woi_duration_us); + + count_rate_total =3D (uint32_t)pdata->peak_signal_count_rate_mcps + (uin= t32_t)pdata->ambient_count_rate_mcps; + + if (histo_merge_nb > 1) + count_rate_total /=3D histo_merge_nb; + + pdata->total_rate_per_spad_mcps =3D VL53LX_rate_per_spad_maths(0x06, cou= nt_rate_total, pdata->VL53LX_p_004, 0xFFFF); + + pdata->VL53LX_p_009 =3D VL53LX_events_per_spad_maths(pdata->VL53LX_p_010= , pdata->VL53LX_p_004, pdata->peak_duration_us); + } + + return status; +} + +VL53LX_Error VL53LX_f_025( + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_hist_post_process_config_t *ppost_cfg, + VL53LX_histogram_bin_data_t *pbins_input, + VL53LX_histogram_bin_data_t *pxtalk, + VL53LX_hist_gen3_algo_private_data_t *palgo3, + VL53LX_hist_gen4_algo_filtered_data_t *pfiltered, + VL53LX_hist_gen3_dmax_private_data_t *pdmax_algo, + VL53LX_range_results_t *presults, + uint8_t histo_merge_nb) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_hist_pulse_data_t *ppulse_data; + VL53LX_range_data_t *prange_data; + uint8_t p =3D 0; + VL53LX_histogram_bin_data_t *pB =3D &(palgo3->VL53LX_p_006); + + VL53LX_f_003(palgo3); + + memcpy(&(palgo3->VL53LX_p_006), pbins_input, sizeof(VL53LX_histogram_bin_= data_t)); + presults->cfg_device_state =3D pbins_input->cfg_device_state; + presults->rd_device_state =3D pbins_input->rd_device_state; + presults->zone_id =3D pbins_input->zone_id; + presults->stream_count =3D pbins_input->result__stream_count; + presults->wrap_dmax_mm =3D 0; + presults->max_results =3D VL53LX_MAX_RANGE_RESULTS; + presults->active_results =3D 0; + + for (p =3D 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) + presults->VL53LX_p_022[p] =3D 0; + + VL53LX_hist_calc_zero_distance_phase(&(palgo3->VL53LX_p_006)); + + VL53LX_hist_estimate_ambient_from_thresholded_bins((int32_t)ppost_cfg->am= bient_thresh_sigma0, &(palgo3->VL53LX_p_006)); + + VL53LX_hist_estimate_ambient_from_ambient_bins(&(palgo3->VL53LX_p_006)); + + VL53LX_hist_remove_ambient_bins(&(palgo3->VL53LX_p_006)); + + if (ppost_cfg->algo__crosstalk_compensation_enable > 0) + VL53LX_f_005(pxtalk, &(palgo3->VL53LX_p_006), &(palgo3->VL53LX_p_047)); + + pdmax_cfg->ambient_thresh_sigma =3D ppost_cfg->ambient_thresh_sigma1; + + for (p =3D 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) { + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D + VL53LX_f_001(pdmax_cfg->target_reflectance_for_dmax_calc[p], pdmax_cal,= pdmax_cfg, &(palgo3->VL53LX_p_006), pdmax_algo, &(presults->VL53LX_p_022[p= ])); + } + } + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D + VL53LX_f_006( + ppost_cfg->ambient_thresh_events_scaler, + (int32_t)pdmax_cfg->ambient_thresh_sigma, + (int32_t)ppost_cfg->min_ambient_thresh_events, + ppost_cfg->algo__crosstalk_compensation_enable, + &(palgo3->VL53LX_p_006), + &(palgo3->VL53LX_p_047), + palgo3); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_007(palgo3); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_008(palgo3); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_009(palgo3); + + for (p =3D 0; p < palgo3->VL53LX_p_046; p++) { + ppulse_data =3D &(palgo3->VL53LX_p_003[p]); + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_010(p, &(palgo3->VL53LX_p_006), palgo3); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_011(p, &(palgo3->VL53LX_p_006), palgo3, pB->VL53LX_= p_028, &(palgo3->VL53LX_p_048)); + + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_f_011(p, &(palgo3->VL53LX_p_006), palgo3, 0, &(palgo3= ->VL53LX_p_049)); + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_f_011(p, &(palgo3->VL53LX_p_047), palgo3, 0, &(palgo3= ->VL53LX_p_050)); + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_026(p, &(palgo3->VL53LX_p_048), palgo3, pfiltered); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_027(p, ppost_cfg->noise_threshold, pfiltered, palgo= 3); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D + VL53LX_f_014( + ppulse_data->VL53LX_p_023, + ppost_cfg->sigma_estimator__sigma_ref_mm, + palgo3->VL53LX_p_030, + ppulse_data->VL53LX_p_051, + ppost_cfg->algo__crosstalk_compensation_enable, + &(palgo3->VL53LX_p_048), + &(palgo3->VL53LX_p_049), + &(palgo3->VL53LX_p_050), + &(ppulse_data->VL53LX_p_002)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_015(p, 1, &(palgo3->VL53LX_p_006), palgo3); + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_016(ppost_cfg->hist_target_order, palgo3); + + for (p =3D 0; p < palgo3->VL53LX_p_046; p++) { + ppulse_data =3D &(palgo3->VL53LX_p_003[p]); + if (!(presults->active_results < presults->max_results)) + continue; + + if (ppulse_data->VL53LX_p_010 > ppost_cfg->signal_total_events_limit && = ppulse_data->VL53LX_p_023 < 0xFF) { + prange_data =3D &(presults->VL53LX_p_003[presults->active_results]); + if (status =3D=3D VL53LX_ERROR_NONE) + VL53LX_f_017( + presults->active_results, + ppost_cfg->valid_phase_low, + ppost_cfg->valid_phase_high, + ppost_cfg->sigma_thresh, + &(palgo3->VL53LX_p_006), + ppulse_data, + prange_data); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_f_018(pB->vcsel_width, pB->VL53LX_p_015, pB->total_p= eriods_elapsed, pB->result__dss_actual_effective_spads, prange_data, histo_= merge_nb); + + if (status =3D=3D VL53LX_ERROR_NONE) + VL53LX_f_019(ppost_cfg->gain_factor, ppost_cfg->range_offset_mm, prang= e_data); + presults->active_results++; + } + } + return status; +} + +VL53LX_Error VL53LX_hist_process_data( + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_hist_post_process_config_t *ppost_cfg, + VL53LX_histogram_bin_data_t *pbins_input, + VL53LX_xtalk_histogram_data_t *pxtalk_shape, + uint8_t *pArea1, + uint8_t *pArea2, + VL53LX_range_results_t *presults, + uint8_t *HistMergeNumber) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_hist_gen3_algo_private_data_t *palgo_gen3 =3D (VL53LX_hist_gen3_al= go_private_data_t *) pArea1; + VL53LX_hist_gen4_algo_filtered_data_t *pfiltered4 =3D (VL53LX_hist_gen4_a= lgo_filtered_data_t *) pArea2; + VL53LX_hist_gen3_dmax_private_data_t dmax_algo_gen3; + VL53LX_hist_gen3_dmax_private_data_t *pdmax_algo_gen3 =3D &dmax_algo_gen= 3; + VL53LX_histogram_bin_data_t bins_averaged; + VL53LX_histogram_bin_data_t *pbins_averaged =3D &bins_averaged; + VL53LX_range_data_t *pdata; + uint32_t xtalk_rate_kcps =3D 0; + uint32_t max_xtalk_rate_per_spad_kcps =3D 0; + uint8_t xtalk_enable =3D 0; + uint8_t r =3D 0; + uint8_t t =3D 0; + uint32_t XtalkDetectMaxSigma =3D 0; + int16_t delta_mm =3D 0; + + VL53LX_f_031(pbins_input, pbins_averaged); + + VL53LX_init_histogram_bin_data_struct(0, pxtalk_shape->xtalk_shape.VL53LX= _p_021, &(pxtalk_shape->xtalk_hist_removed)); + VL53LX_copy_xtalk_bin_data_to_histogram_data_struct(&(pxtalk_shape->xtalk= _shape), &(pxtalk_shape->xtalk_hist_removed)); + + if ((status =3D=3D VL53LX_ERROR_NONE) && (ppost_cfg->algo__crosstalk_comp= ensation_enable > 0)) + status =3D + VL53LX_f_032( + ppost_cfg->algo__crosstalk_compensation_plane_offset_kcps, + ppost_cfg->algo__crosstalk_compensation_x_plane_gradient_kcps, + ppost_cfg->algo__crosstalk_compensation_y_plane_gradient_kcps, + 0, + 0, + pbins_input->result__dss_actual_effective_spads, + pbins_input->roi_config__user_roi_centre_spad, + pbins_input->roi_config__user_roi_requested_global_xy_size, + &(xtalk_rate_kcps)); + + if ((status =3D=3D VL53LX_ERROR_NONE) && (ppost_cfg->algo__crosstalk_comp= ensation_enable > 0)) + status =3D VL53LX_f_033(pbins_averaged, &(pxtalk_shape->xtalk_shape), xt= alk_rate_kcps, &(pxtalk_shape->xtalk_hist_removed)); + + presults->xmonitor.total_periods_elapsed =3D pbins_averaged->total_period= s_elapsed; + presults->xmonitor.VL53LX_p_004 =3D pbins_averaged->result__dss_actual_ef= fective_spads; + + presults->xmonitor.peak_signal_count_rate_mcps =3D 0; + presults->xmonitor.VL53LX_p_009 =3D 0; + + presults->xmonitor.range_id =3D 0; + presults->xmonitor.range_status =3D VL53LX_DEVICEERROR_NOUPDATE; + + xtalk_enable =3D 0; + if (ppost_cfg->algo__crosstalk_compensation_enable > 0) + xtalk_enable =3D 1; + + for (r =3D 0 ; r <=3D xtalk_enable ; r++) { + ppost_cfg->algo__crosstalk_compensation_enable =3D r; + status =3D + VL53LX_f_025( + pdmax_cal, + pdmax_cfg, + ppost_cfg, + pbins_averaged, + &(pxtalk_shape->xtalk_hist_removed), + palgo_gen3, + pfiltered4, + pdmax_algo_gen3, + presults, + *HistMergeNumber); + + if (!(status =3D=3D VL53LX_ERROR_NONE && r =3D=3D 0)) + continue; + + if (presults->active_results =3D=3D 0) { + pdata =3D &(presults->VL53LX_p_003[0]); + pdata->ambient_count_rate_mcps =3D pdmax_algo_gen3->VL53LX_p_034; + pdata->VL53LX_p_004 =3D pdmax_algo_gen3->VL53LX_p_004; + } + + max_xtalk_rate_per_spad_kcps =3D (uint32_t)(ppost_cfg->algo__crosstalk_d= etect_max_valid_rate_kcps); + max_xtalk_rate_per_spad_kcps *=3D (uint32_t)(*HistMergeNumber); + max_xtalk_rate_per_spad_kcps <<=3D 4; + + for (t =3D 0 ; t < presults->active_results ; t++) { + pdata =3D &(presults->VL53LX_p_003[t]); + if (pdata->max_range_mm > pdata->min_range_mm) + delta_mm =3D pdata->max_range_mm - pdata->min_range_mm; + else + delta_mm =3D pdata->min_range_mm - pdata->max_range_mm; + + XtalkDetectMaxSigma =3D ppost_cfg->algo__crosstalk_detect_max_sigma_mm; + XtalkDetectMaxSigma *=3D (uint32_t)(*HistMergeNumber); + XtalkDetectMaxSigma <<=3D 5; + if (pdata->median_range_mm > + ppost_cfg->algo__crosstalk_detect_min_valid_range_mm && + pdata->median_range_mm < + ppost_cfg->algo__crosstalk_detect_max_valid_range_mm && + pdata->VL53LX_p_009 < + max_xtalk_rate_per_spad_kcps && + pdata->VL53LX_p_002 < XtalkDetectMaxSigma && + delta_mm < + ppost_cfg->algo__crosstalk_detect_min_max_tolerance) { + memcpy(&(presults->xmonitor), pdata, sizeof(VL53LX_range_data_t)); + } + } + } + ppost_cfg->algo__crosstalk_compensation_enable =3D xtalk_enable; + return status; +} + +VL53LX_Error VL53LX_hist_wrap_dmax(VL53LX_hist_post_process_config_t *phis= tpostprocess, VL53LX_histogram_bin_data_t *pcurrent, int16_t *pwrap_dmax_mm) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint32_t pll_period_mm =3D 0; + uint32_t wrap_dmax_phase =3D 0; + uint32_t range_mm =3D 0; + + *pwrap_dmax_mm =3D 0; + + if (pcurrent->VL53LX_p_015 !=3D 0) { + pll_period_mm =3D VL53LX_calc_pll_period_mm(pcurrent->VL53LX_p_015); + + wrap_dmax_phase =3D (uint32_t)phistpostprocess->valid_phase_high << 8; + + range_mm =3D wrap_dmax_phase * pll_period_mm; + range_mm =3D (range_mm + (1<<14)) >> 15; + + *pwrap_dmax_mm =3D (int16_t)range_mm; + } + return status; +} + +VL53LX_Error VL53LX_ipp_hist_process_data( + VL53LX_DEV Dev, + VL53LX_dmax_calibration_data_t *pdmax_cal, + VL53LX_hist_gen3_dmax_config_t *pdmax_cfg, + VL53LX_hist_post_process_config_t *ppost_cfg, + VL53LX_histogram_bin_data_t *pbins, + VL53LX_xtalk_histogram_data_t *pxtalk, + uint8_t *pArea1, + uint8_t *pArea2, + uint8_t *phisto_merge_nb, + VL53LX_range_results_t *presults) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + SUPPRESS_UNUSED_WARNING(Dev); + + status =3D VL53LX_hist_process_data(pdmax_cal, pdmax_cfg, ppost_cfg, pbin= s, pxtalk, pArea1, pArea2, presults, phisto_merge_nb); + return status; +} + +VL53LX_Error VL53LX_hist_events_consistency_check( + uint8_t event_sigma, + uint16_t min_effective_spad_count, + VL53LX_zone_hist_info_t *phist_prev, + VL53LX_object_data_t *prange_prev, + VL53LX_range_data_t *prange_curr, + int32_t *pevents_tolerance, + int32_t *pevents_delta, + VL53LX_DeviceError *prange_status) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + int64_t tmpp =3D 0; + int64_t tmpc =3D 0; + int64_t events_scaler =3D 0; + int64_t events_scaler_sq =3D 0; + int64_t c_signal_events =3D 0; + int64_t c_sig_noise_sq =3D 0; + int64_t c_amb_noise_sq =3D 0; + int64_t p_amb_noise_sq =3D 0; + int32_t p_signal_events =3D 0; + uint32_t noise_sq_sum =3D 0; + + if (event_sigma =3D=3D 0) { + *prange_status =3D VL53LX_DEVICEERROR_RANGECOMPLETE; + return status; + } + + tmpp =3D 1 + (int64_t)phist_prev->total_periods_elapsed; + tmpp *=3D (int64_t)phist_prev->result__dss_actual_effective_spads; + + tmpc =3D 1 + (int64_t)prange_curr->total_periods_elapsed; + tmpc *=3D (int64_t)prange_curr->VL53LX_p_004; + + events_scaler =3D tmpp * 4096; + if (tmpc !=3D 0) { + events_scaler +=3D (tmpc/2); + events_scaler =3D do_division_s(events_scaler, tmpc); + } + + events_scaler_sq =3D events_scaler * events_scaler; + events_scaler_sq +=3D 2048; + events_scaler_sq /=3D 4096; + + c_signal_events =3D (int64_t)prange_curr->VL53LX_p_017; + c_signal_events -=3D (int64_t)prange_curr->VL53LX_p_016; + c_signal_events *=3D (int64_t)events_scaler; + c_signal_events +=3D 2048; + c_signal_events /=3D 4096; + + c_sig_noise_sq =3D (int64_t)events_scaler_sq; + c_sig_noise_sq *=3D (int64_t)prange_curr->VL53LX_p_017; + c_sig_noise_sq +=3D 2048; + c_sig_noise_sq /=3D 4096; + + c_amb_noise_sq =3D (int64_t)events_scaler_sq; + c_amb_noise_sq *=3D (int64_t)prange_curr->VL53LX_p_016; + c_amb_noise_sq +=3D 2048; + c_amb_noise_sq /=3D 4096; + + c_amb_noise_sq +=3D 2; + c_amb_noise_sq /=3D 4; + + p_amb_noise_sq =3D (int64_t)prange_prev->VL53LX_p_016; + + p_amb_noise_sq +=3D 2; + p_amb_noise_sq /=3D 4; + + noise_sq_sum =3D (uint32_t)prange_prev->VL53LX_p_017 + (uint32_t)c_sig_no= ise_sq + (uint32_t)p_amb_noise_sq + (uint32_t)c_amb_noise_sq; + + *pevents_tolerance =3D (int32_t)VL53LX_isqrt(noise_sq_sum * 16); + *pevents_tolerance *=3D (int32_t)event_sigma; + *pevents_tolerance +=3D 32; + *pevents_tolerance /=3D 64; + + p_signal_events =3D (int32_t)prange_prev->VL53LX_p_017; + p_signal_events -=3D (int32_t)prange_prev->VL53LX_p_016; + + if ((int32_t)c_signal_events > p_signal_events) + *pevents_delta =3D (int32_t)c_signal_events - p_signal_events; + else + *pevents_delta =3D p_signal_events - (int32_t)c_signal_events; + + if (*pevents_delta > *pevents_tolerance && prange_curr->VL53LX_p_004 > mi= n_effective_spad_count) + *prange_status =3D VL53LX_DEVICEERROR_EVENTCONSISTENCY; + else + *prange_status =3D VL53LX_DEVICEERROR_RANGECOMPLETE; + + return status; +} + +VL53LX_Error VL53LX_hist_merged_pulse_check(int16_t min_max_tolerance_mm, = VL53LX_range_data_t *pdata, VL53LX_DeviceError *prange_status) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + int16_t delta_mm =3D 0; + + if (pdata->max_range_mm > pdata->min_range_mm) + delta_mm =3D pdata->max_range_mm - pdata->min_range_mm; + else + delta_mm =3D pdata->min_range_mm - pdata->max_range_mm; + + if (min_max_tolerance_mm > 0 && delta_mm > min_max_tolerance_mm) + *prange_status =3D VL53LX_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE; + else + *prange_status =3D VL53LX_DEVICEERROR_RANGECOMPLETE; + + return status; +} + +VL53LX_Error VL53LX_hist_phase_consistency_check(VL53LX_DEV Dev, VL53LX_zo= ne_hist_info_t *phist_prev, VL53LX_zone_objects_t *prange_prev, VL53LX_rang= e_results_t *prange_curr) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t lc =3D 0; + uint8_t p =3D 0; + uint16_t phase_delta =3D 0; + uint16_t phase_tolerance =3D 0; + int32_t events_delta =3D 0; + int32_t events_tolerance =3D 0; + uint8_t event_sigma; + uint16_t event_min_spad_count; + uint16_t min_max_tolerance; + uint8_t pht; + + VL53LX_DeviceError range_status =3D 0; + + event_sigma =3D pdev->histpostprocess.algo__consistency_check__event_sigm= a; + event_min_spad_count =3D pdev->histpostprocess.algo__consistency_check__e= vent_min_spad_count; + min_max_tolerance =3D pdev->histpostprocess.algo__consistency_check__min_= max_tolerance; + pht =3D pdev->histpostprocess.algo__consistency_check__phase_tolerance; + phase_tolerance =3D (uint16_t)pht; + phase_tolerance =3D phase_tolerance << 8; + + if (prange_prev->rd_device_state !=3D VL53LX_DEVICESTATE_RANGING_GATHER_D= ATA && + prange_prev->rd_device_state !=3D VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA) + return status; + + if (phase_tolerance =3D=3D 0) + return status; + + for (lc =3D 0; lc < prange_curr->active_results; lc++) { + if (!((prange_curr->VL53LX_p_003[lc].range_status =3D=3D + VL53LX_DEVICEERROR_RANGECOMPLETE) || + (prange_curr->VL53LX_p_003[lc].range_status =3D=3D + VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK))) + continue; + + if (prange_prev->active_objects =3D=3D 0) + prange_curr->VL53LX_p_003[lc].range_status =3D VL53LX_DEVICEERROR_PREV_= RANGE_NO_TARGETS; + else + prange_curr->VL53LX_p_003[lc].range_status =3D VL53LX_DEVICEERROR_PHASE= CONSISTENCY; + + for (p =3D 0; p < prange_prev->active_objects; p++) { + if (prange_curr->VL53LX_p_003[lc].VL53LX_p_011 > prange_prev->VL53LX_p_= 003[p].VL53LX_p_011) { + phase_delta =3D prange_curr->VL53LX_p_003[lc].VL53LX_p_011 - prange_pr= ev->VL53LX_p_003[p].VL53LX_p_011; + } else { + phase_delta =3D prange_prev->VL53LX_p_003[p].VL53LX_p_011 - prange_cur= r->VL53LX_p_003[lc].VL53LX_p_011; + } + + if (phase_delta < phase_tolerance) { + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D + VL53LX_hist_events_consistency_check( + event_sigma, + event_min_spad_count, + phist_prev, + &(prange_prev->VL53LX_p_003[p]), + &(prange_curr->VL53LX_p_003[lc]), + &events_tolerance, + &events_delta, + &range_status); + + if (status =3D=3D VL53LX_ERROR_NONE && range_status =3D=3D VL53LX_DEVI= CEERROR_RANGECOMPLETE) + status =3D VL53LX_hist_merged_pulse_check(min_max_tolerance, &(prange= _curr->VL53LX_p_003[lc]), &range_status); + + prange_curr->VL53LX_p_003[lc].range_status =3D range_status; + } + } + } + return status; +} + +VL53LX_Error VL53LX_hist_xmonitor_consistency_check(VL53LX_DEV Dev, VL53LX= _zone_hist_info_t *phist_prev, VL53LX_zone_objects_t *prange_prev, VL53LX_r= ange_data_t *prange_curr) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + int32_t events_delta =3D 0; + int32_t events_tolerance =3D 0; + uint8_t event_sigma; + uint16_t min_spad_count; + + event_sigma =3D pdev->histpostprocess.algo__crosstalk_detect_event_sigma; + min_spad_count =3D pdev->histpostprocess.algo__consistency_check__event_m= in_spad_count; + + if (prange_curr->range_status =3D=3D VL53LX_DEVICEERROR_RANGECOMPLETE || + prange_curr->range_status =3D=3D VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRA= P_CHECK || + prange_curr->range_status =3D=3D VL53LX_DEVICEERROR_EVENTCONSISTENCY) { + + if (prange_prev->xmonitor.range_status =3D=3D VL53LX_DEVICEERROR_RANGECO= MPLETE || + prange_prev->xmonitor.range_status =3D=3D VL53LX_DEVICEERROR_RANGECOMPL= ETE_NO_WRAP_CHECK || + prange_prev->xmonitor.range_status =3D=3D VL53LX_DEVICEERROR_EVENTCONSI= STENCY) { + prange_curr->range_status =3D VL53LX_DEVICEERROR_RANGECOMPLETE; + + status =3D + VL53LX_hist_events_consistency_check( + event_sigma, + min_spad_count, + phist_prev, + &(prange_prev->xmonitor), + prange_curr, + &events_tolerance, + &events_delta, + &(prange_curr->range_status)); + } + } + return status; +} + +void VL53LX_init_system_results(VL53LX_system_results_t *pdata) +{ + pdata->result__interrupt_status =3D 0xFF; + pdata->result__range_status =3D 0xFF; + pdata->result__report_status =3D 0xFF; + pdata->result__stream_count =3D 0xFF; + pdata->result__dss_actual_effective_spads_sd0 =3D 0xFFFF; + pdata->result__peak_signal_count_rate_mcps_sd0 =3D 0xFFFF; + pdata->result__ambient_count_rate_mcps_sd0 =3D 0xFFFF; + pdata->result__sigma_sd0 =3D 0xFFFF; + pdata->result__phase_sd0 =3D 0xFFFF; + pdata->result__final_crosstalk_corrected_range_mm_sd0 =3D 0xFFFF; + pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 =3D 0x= FFFF; + pdata->result__mm_inner_actual_effective_spads_sd0 =3D 0xFFFF; + pdata->result__mm_outer_actual_effective_spads_sd0 =3D 0xFFFF; + pdata->result__avg_signal_count_rate_mcps_sd0 =3D 0xFFFF; + pdata->result__dss_actual_effective_spads_sd1 =3D 0xFFFF; + pdata->result__peak_signal_count_rate_mcps_sd1 =3D 0xFFFF; + pdata->result__ambient_count_rate_mcps_sd1 =3D 0xFFFF; + pdata->result__sigma_sd1 =3D 0xFFFF; + pdata->result__phase_sd1 =3D 0xFFFF; + pdata->result__final_crosstalk_corrected_range_mm_sd1 =3D 0xFFFF; + pdata->result__spare_0_sd1 =3D 0xFFFF; + pdata->result__spare_1_sd1 =3D 0xFFFF; + pdata->result__spare_2_sd1 =3D 0xFFFF; + pdata->result__spare_3_sd1 =3D 0xFF; +} + +void VL53LX_hist_copy_results_to_sys_and_core( + VL53LX_histogram_bin_data_t *pbins, + VL53LX_range_results_t *phist, + VL53LX_system_results_t *psys, + VL53LX_core_results_t *pcore) +{ + uint8_t i =3D 0; + VL53LX_range_data_t *pdata; + + VL53LX_init_system_results(psys); + + psys->result__interrupt_status =3D pbins->result__interrupt_status; + psys->result__range_status =3D phist->active_results; + psys->result__report_status =3D pbins->result__report_status; + psys->result__stream_count =3D pbins->result__stream_count; + + pdata =3D &(phist->VL53LX_p_003[0]); + + for (i =3D 0; i < phist->active_results; i++) { + switch (i) { + case 0: + psys->result__dss_actual_effective_spads_sd0 =3D pdata->VL53LX_p_004; + psys->result__peak_signal_count_rate_mcps_sd0 =3D pdata->peak_signal_co= unt_rate_mcps; + psys->result__avg_signal_count_rate_mcps_sd0 =3D pdata->avg_signal_coun= t_rate_mcps; + psys->result__ambient_count_rate_mcps_sd0 =3D pdata->ambient_count_rate= _mcps; + psys->result__sigma_sd0 =3D pdata->VL53LX_p_002; + psys->result__phase_sd0 =3D pdata->VL53LX_p_011; + psys->result__final_crosstalk_corrected_range_mm_sd0 =3D (uint16_t)pdat= a->median_range_mm; + psys->result__phase_sd1 =3D pdata->zero_distance_phase; + pcore->result_core__ranging_total_events_sd0 =3D pdata->VL53LX_p_017; + pcore->result_core__signal_total_events_sd0 =3D pdata->VL53LX_p_010; + pcore->result_core__total_periods_elapsed_sd0 =3D pdata->total_periods_= elapsed; + pcore->result_core__ambient_window_events_sd0 =3D pdata->VL53LX_p_016; + break; + case 1: + psys->result__dss_actual_effective_spads_sd1 =3D pdata->VL53LX_p_004; + psys->result__peak_signal_count_rate_mcps_sd1 =3D pdata->peak_signal_co= unt_rate_mcps; + psys->result__ambient_count_rate_mcps_sd1 =3D pdata->ambient_count_rate= _mcps; + psys->result__sigma_sd1 =3D pdata->VL53LX_p_002; + psys->result__phase_sd1 =3D pdata->VL53LX_p_011; + psys->result__final_crosstalk_corrected_range_mm_sd1 =3D (uint16_t)pdat= a->median_range_mm; + pcore->result_core__ranging_total_events_sd1 =3D pdata->VL53LX_p_017; + pcore->result_core__signal_total_events_sd1 =3D pdata->VL53LX_p_010; + pcore->result_core__total_periods_elapsed_sd1 =3D pdata->total_periods_= elapsed; + pcore->result_core__ambient_window_events_sd1 =3D pdata->VL53LX_p_016; + break; + } + pdata++; + } +} + +VL53LX_Error VL53LX_dynamic_zone_update(VL53LX_DEV Dev, VL53LX_range_resul= ts_t *presults) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev= ); + VL53LX_zone_private_dyn_cfgs_t *pZ =3D &(pres->zone_dyn_cfgs); + + uint8_t zone_id =3D pdev->ll_state.rd_zone_id; + uint8_t i; + uint16_t max_total_rate_per_spads; + uint16_t target_rate =3D pdev->stat_cfg.dss_config__target_total_rate_mc= ps; + uint32_t temp =3D 0xFFFF; +#ifdef VL53LX_LOG_ENABLE + uint16_t eff_spad_cnt =3D + pZ->VL53LX_p_003[zone_id].dss_requested_effective_spad_count; +#endif + + pZ->VL53LX_p_003[zone_id].dss_requested_effective_spad_count =3D 0; + + max_total_rate_per_spads =3D presults->VL53LX_p_003[0].total_rate_per_spa= d_mcps; + + for (i =3D 1; i < presults->active_results; i++) { + if (presults->VL53LX_p_003[i].total_rate_per_spad_mcps > max_total_rate_= per_spads) + max_total_rate_per_spads =3D presults->VL53LX_p_003[i].total_rate_per_s= pad_mcps; + } + + if (max_total_rate_per_spads =3D=3D 0) { + temp =3D 0xFFFF; + } else { + temp =3D target_rate << 14; + temp =3D temp / max_total_rate_per_spads; + if (temp > 0xFFFF) + temp =3D 0xFFFF; + } + + pZ->VL53LX_p_003[zone_id].dss_requested_effective_spad_count =3D (uint16_= t)temp; + + return status; +} + +void VL53LX_copy_hist_bins_to_static_cfg(VL53LX_histogram_config_t *phisto= gram, VL53LX_static_config_t *pstatic, VL53LX_timing_config_t *ptiming) +{ + pstatic->sigma_estimator__effective_pulse_width_ns =3D phistogram->histog= ram_config__high_amb_even_bin_0_1; + pstatic->sigma_estimator__effective_ambient_width_ns =3D phistogram->hist= ogram_config__high_amb_even_bin_2_3; + pstatic->sigma_estimator__sigma_ref_mm =3D phistogram->histogram_config__= high_amb_even_bin_4_5; + pstatic->algo__crosstalk_compensation_valid_height_mm =3D phistogram->his= togram_config__high_amb_odd_bin_0_1; + pstatic->spare_host_config__static_config_spare_0 =3D phistogram->histogr= am_config__high_amb_odd_bin_2_3; + pstatic->spare_host_config__static_config_spare_1 =3D phistogram->histogr= am_config__high_amb_odd_bin_4_5; + pstatic->algo__range_ignore_threshold_mcps =3D + (((uint16_t)phistogram->histogram_config__mid_amb_even_bin_0_1) + << 8) + + (uint16_t)phistogram->histogram_config__mid_amb_even_bin_2_3; + pstatic->algo__range_ignore_valid_height_mm =3D phistogram->histogram_con= fig__mid_amb_even_bin_4_5; + pstatic->algo__range_min_clip =3D phistogram->histogram_config__mid_amb_o= dd_bin_0_1; + pstatic->algo__consistency_check__tolerance =3D phistogram->histogram_con= fig__mid_amb_odd_bin_2; + pstatic->spare_host_config__static_config_spare_2 =3D phistogram->histogr= am_config__mid_amb_odd_bin_3_4; + pstatic->sd_config__reset_stages_msb =3D phistogram->histogram_config__mi= d_amb_odd_bin_5; + ptiming->range_config__sigma_thresh =3D + (((uint16_t)phistogram->histogram_config__low_amb_even_bin_0_1) + << 8) + + (uint16_t)phistogram->histogram_config__low_amb_even_bin_2_3; + ptiming->range_config__min_count_rate_rtn_limit_mcps =3D + (((uint16_t)phistogram->histogram_config__low_amb_even_bin_4_5) + << 8) + + (uint16_t)phistogram->histogram_config__low_amb_odd_bin_0_1; + ptiming->range_config__valid_phase_low =3D + phistogram->histogram_config__low_amb_odd_bin_2_3; + ptiming->range_config__valid_phase_high =3D + phistogram->histogram_config__low_amb_odd_bin_4_5; +} + +VL53LX_Error VL53LX_multizone_hist_bins_update(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_histogram_config_t *phist_cfg =3D &(pdev->hist_cfg); + + if (status =3D=3D VL53LX_ERROR_NONE) { + VL53LX_copy_hist_bins_to_static_cfg(phist_cfg, &(pdev->stat_cfg), &(pdev= ->tim_cfg)); + } + return status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_calc_required_samples(VL53LX_= DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev); + VL53LX_smudge_corrector_config_t *pconfig =3D &(pdev->smudge_correct_conf= ig); + VL53LX_smudge_corrector_internals_t *pint =3D &(pdev->smudge_corrector_in= ternals); + VL53LX_range_results_t *presults =3D &(pres->range_results); + VL53LX_range_data_t *pxmonitor =3D &(presults->xmonitor); + + uint32_t peak_duration_us =3D pxmonitor->peak_duration_us; + uint64_t temp64a; + uint64_t temp64z; + + temp64a =3D pxmonitor->VL53LX_p_017 + pxmonitor->VL53LX_p_016; + if (peak_duration_us =3D=3D 0) + peak_duration_us =3D 1000; + temp64a =3D do_division_u((temp64a * 1000), peak_duration_us); + temp64a =3D do_division_u((temp64a * 1000), peak_duration_us); + + temp64z =3D pconfig->noise_margin * pxmonitor->VL53LX_p_004; + if (temp64z =3D=3D 0) + temp64z =3D 1; + temp64a =3D temp64a * 1000 * 256; + temp64a =3D do_division_u(temp64a, temp64z); + temp64a =3D temp64a * 1000 * 256; + temp64a =3D do_division_u(temp64a, temp64z); + + pint->required_samples =3D (uint32_t)temp64a; + + if (pint->required_samples < 2) + pint->required_samples =3D 2; + + return status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_calc_new_xtalk( + VL53LX_DEV Dev, + uint32_t xtalk_offset_out, + VL53LX_smudge_corrector_config_t *pconfig, + VL53LX_smudge_corrector_data_t *pout, + uint8_t add_smudge, + uint8_t soft_update + ) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + int16_t x_gradient_scaler; + int16_t y_gradient_scaler; + uint32_t orig_xtalk_offset; + int16_t orig_x_gradient; + int16_t orig_y_gradient; + uint8_t histo_merge_nb; + uint8_t i; + int32_t itemp32; + uint32_t SmudgeFactor; + VL53LX_xtalk_config_t *pX =3D &(pdev->xtalk_cfg); + VL53LX_xtalk_calibration_results_t *pC =3D &(pdev->xtalk_cal); + uint32_t *pcpo; + uint32_t max, nXtalk, cXtalk; + uint32_t incXtalk, cval; + + if (add_smudge =3D=3D 1) { + pout->algo__crosstalk_compensation_plane_offset_kcps =3D (uint32_t)xtalk= _offset_out + (uint32_t)pconfig->smudge_margin; + } else { + pout->algo__crosstalk_compensation_plane_offset_kcps =3D (uint32_t)xtalk= _offset_out; + } + + orig_xtalk_offset =3D pX->nvm_default__crosstalk_compensation_plane_offse= t_kcps; + orig_x_gradient =3D pX->nvm_default__crosstalk_compensation_x_plane_gradi= ent_kcps; + orig_y_gradient =3D pX->nvm_default__crosstalk_compensation_y_plane_gradi= ent_kcps; + + if (((pconfig->user_scaler_set =3D=3D 0) || (pconfig->scaler_calc_method = =3D=3D 1)) && (pC->algo__crosstalk_compensation_plane_offset_kcps !=3D 0)) { + VL53LX_compute_histo_merge_nb(Dev, &histo_merge_nb); + + if (histo_merge_nb =3D=3D 0) + histo_merge_nb =3D 1; + if (pdev->tuning_parms.tp_hist_merge !=3D 1) + orig_xtalk_offset =3D pC->algo__crosstalk_compensation_plane_offset_kcp= s; + else + orig_xtalk_offset =3D pC->algo__xtalk_cpo_HistoMerge_kcps[histo_merge_n= b-1]; + + orig_x_gradient =3D pC->algo__crosstalk_compensation_x_plane_gradient_kc= ps; + orig_y_gradient =3D pC->algo__crosstalk_compensation_y_plane_gradient_kc= ps; + } + + if ((pconfig->user_scaler_set =3D=3D 0) && (orig_x_gradient =3D=3D 0)) + pout->gradient_zero_flag |=3D 0x01; + + if ((pconfig->user_scaler_set =3D=3D 0) && (orig_y_gradient =3D=3D 0)) + pout->gradient_zero_flag |=3D 0x02; + + if (orig_xtalk_offset =3D=3D 0) + orig_xtalk_offset =3D 1; + + if (pconfig->user_scaler_set =3D=3D 1) { + x_gradient_scaler =3D pconfig->x_gradient_scaler; + y_gradient_scaler =3D pconfig->y_gradient_scaler; + } else { + x_gradient_scaler =3D (int16_t)do_division_s((((int32_t)orig_x_gradient)= << 6), orig_xtalk_offset); + pconfig->x_gradient_scaler =3D x_gradient_scaler; + y_gradient_scaler =3D (int16_t)do_division_s((((int32_t)orig_y_gradient)= << 6), orig_xtalk_offset); + pconfig->y_gradient_scaler =3D y_gradient_scaler; + } + + if (pconfig->scaler_calc_method =3D=3D 0) { + itemp32 =3D (int32_t)(pout->algo__crosstalk_compensation_plane_offset_kc= ps * x_gradient_scaler); + itemp32 =3D itemp32 >> 6; + if (itemp32 > 0xFFFF) + itemp32 =3D 0xFFFF; + + pout->algo__crosstalk_compensation_x_plane_gradient_kcps =3D (int16_t)it= emp32; + + itemp32 =3D (int32_t)(pout->algo__crosstalk_compensation_plane_offset_kc= ps * y_gradient_scaler); + itemp32 =3D itemp32 >> 6; + if (itemp32 > 0xFFFF) + itemp32 =3D 0xFFFF; + + pout->algo__crosstalk_compensation_y_plane_gradient_kcps =3D (int16_t)it= emp32; + } else if (pconfig->scaler_calc_method =3D=3D 1) { + itemp32 =3D (int32_t)(orig_xtalk_offset - pout->algo__crosstalk_compensa= tion_plane_offset_kcps); + itemp32 =3D (int32_t)(do_division_s(itemp32, 16)); + itemp32 =3D itemp32 << 2; + itemp32 =3D itemp32 + (int32_t)(orig_x_gradient); + if (itemp32 > 0xFFFF) + itemp32 =3D 0xFFFF; + + pout->algo__crosstalk_compensation_x_plane_gradient_kcps =3D (int16_t)it= emp32; + + itemp32 =3D (int32_t)(orig_xtalk_offset - pout->algo__crosstalk_compensa= tion_plane_offset_kcps); + itemp32 =3D (int32_t)(do_division_s(itemp32, 80)); + itemp32 =3D itemp32 << 2; + itemp32 =3D itemp32 + (int32_t)(orig_y_gradient); + if (itemp32 > 0xFFFF) + itemp32 =3D 0xFFFF; + + pout->algo__crosstalk_compensation_y_plane_gradient_kcps =3D (int16_t)it= emp32; + } + + if ((pconfig->smudge_corr_apply_enabled =3D=3D 1) && (soft_update !=3D 1)= ) { + pout->new_xtalk_applied_flag =3D 1; + nXtalk =3D pout->algo__crosstalk_compensation_plane_offset_kcps; + VL53LX_compute_histo_merge_nb(Dev, &histo_merge_nb); + max =3D pdev->tuning_parms.tp_hist_merge_max_size; + pcpo =3D &(pC->algo__xtalk_cpo_HistoMerge_kcps[0]); + if ((histo_merge_nb > 0) && (pdev->tuning_parms.tp_hist_merge =3D=3D 1) = && (nXtalk !=3D 0)) { + cXtalk =3D pX->algo__crosstalk_compensation_plane_offset_kcps; + SmudgeFactor =3D cXtalk * 1000 / nXtalk; + if ((max =3D=3D 0) || (SmudgeFactor >=3D pconfig->max_smudge_factor)) + pout->new_xtalk_applied_flag =3D 0; + else { + incXtalk =3D nXtalk / max; + cval =3D 0; + for (i =3D 0; i < max-1; i++) { + cval +=3D incXtalk; + *pcpo =3D cval; + pcpo++; + } + *pcpo =3D nXtalk; + } + } + if (pout->new_xtalk_applied_flag) { + pX->algo__crosstalk_compensation_plane_offset_kcps =3D + pout->algo__crosstalk_compensation_plane_offset_kcps; + pX->algo__crosstalk_compensation_x_plane_gradient_kcps =3D + pout->algo__crosstalk_compensation_x_plane_gradient_kcps; + pX->algo__crosstalk_compensation_y_plane_gradient_kcps =3D + pout->algo__crosstalk_compensation_y_plane_gradient_kcps; + + if (pconfig->smudge_corr_single_apply =3D=3D 1) { + pconfig->smudge_corr_apply_enabled =3D 0; + pconfig->smudge_corr_single_apply =3D 0; + } + } + } + + if (soft_update !=3D 1) + pout->smudge_corr_valid =3D 1; + + return status; +} + +VL53LX_Error VL53LX_dynamic_xtalk_correction_corrector(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev); + VL53LX_smudge_corrector_config_t *pconfig =3D &(pdev->smudge_correct_conf= ig); + VL53LX_smudge_corrector_internals_t *pint =3D &(pdev->smudge_corrector_in= ternals); + VL53LX_smudge_corrector_data_t *pout =3D &(pres->range_results.smudge_cor= rector_data); + VL53LX_range_results_t *pR =3D &(pres->range_results); + VL53LX_xtalk_config_t *pX =3D &(pdev->xtalk_cfg); + + uint8_t run_smudge_detection =3D 0; + uint8_t merging_complete =3D 0; + uint8_t run_nodetect =3D 0; + uint8_t ambient_check =3D 0; + int32_t itemp32 =3D 0; + uint64_t utemp64 =3D 0; + uint8_t continue_processing =3D CONT_CONTINUE; + uint32_t xtalk_offset_out =3D 0; + uint32_t xtalk_offset_in =3D 0; + uint32_t current_xtalk =3D 0; + uint32_t smudge_margin_adjusted =3D 0; + uint8_t i =3D 0; + uint8_t nodetect_index =3D 0; + uint16_t amr; + uint32_t cco; + uint8_t histo_merge_nb; + + VL53LX_compute_histo_merge_nb(Dev, &histo_merge_nb); + if ((histo_merge_nb =3D=3D 0) || (pdev->tuning_parms.tp_hist_merge !=3D 1= )) + histo_merge_nb =3D 1; + + VL53LX_dynamic_xtalk_correction_output_init(pres); + + ambient_check =3D (pconfig->smudge_corr_ambient_threshold =3D=3D 0) || + ((pconfig->smudge_corr_ambient_threshold * histo_merge_nb) > + ((uint32_t)pR->xmonitor.ambient_count_rate_mcps)); + + merging_complete =3D ((pdev->tuning_parms.tp_hist_merge !=3D 1) || (histo= _merge_nb =3D=3D pdev->tuning_parms.tp_hist_merge_max_size)); + run_smudge_detection =3D (pconfig->smudge_corr_enabled =3D=3D 1) && ambie= nt_check && (pR->xmonitor.range_status =3D=3D VL53LX_DEVICEERROR_RANGECOMPL= ETE) && merging_complete; + + if ((pR->xmonitor.range_status !=3D VL53LX_DEVICEERROR_RANGECOMPLETE) && = (pconfig->smudge_corr_enabled =3D=3D 1)) { + run_nodetect =3D 2; + for (i =3D 0; i < pR->active_results; i++) { + if (pR->VL53LX_p_003[i].range_status =3D=3D VL53LX_DEVICEERROR_RANGECOM= PLETE) { + if (pR->VL53LX_p_003[i].median_range_mm <=3D pconfig->nodetect_min_ran= ge_mm) { + run_nodetect =3D 0; + } else { + if (run_nodetect =3D=3D 2) { + run_nodetect =3D 1; + nodetect_index =3D i; + } + } + } + } + + if (run_nodetect =3D=3D 2) + run_nodetect =3D 0; + + amr =3D pR->VL53LX_p_003[nodetect_index].ambient_count_rate_mcps; + + if (run_nodetect =3D=3D 1) { + utemp64 =3D 1000 * ((uint64_t)amr); + utemp64 =3D utemp64 << 9; + + if (utemp64 < pconfig->nodetect_ambient_threshold) + run_nodetect =3D 1; + else + run_nodetect =3D 0; + } + } + + if (run_smudge_detection) { + pint->nodetect_counter =3D 0; + VL53LX_dynamic_xtalk_correction_calc_required_samples(Dev); + + xtalk_offset_in =3D pR->xmonitor.VL53LX_p_009; + + cco =3D pX->algo__crosstalk_compensation_plane_offset_kcps; + current_xtalk =3D ((uint32_t)cco) << 2; + + smudge_margin_adjusted =3D ((uint32_t)(pconfig->smudge_margin)) << 2; + + itemp32 =3D xtalk_offset_in - current_xtalk + smudge_margin_adjusted; + + if (itemp32 < 0) + itemp32 =3D itemp32 * (-1); + + if (itemp32 > ((int32_t)pconfig->single_xtalk_delta)) { + if ((int32_t)xtalk_offset_in > ((int32_t)current_xtalk - (int32_t)smudg= e_margin_adjusted)) { + pout->single_xtalk_delta_flag =3D 1; + } else { + pout->single_xtalk_delta_flag =3D 2; + } + } + + pint->current_samples =3D pint->current_samples + 1; + + if (pint->current_samples > pconfig->sample_limit) { + pout->sample_limit_exceeded_flag =3D 1; + continue_processing =3D CONT_RESET; + } else { + pint->accumulator =3D pint->accumulator + xtalk_offset_in; + } + + if (pint->current_samples < pint->required_samples) + continue_processing =3D CONT_NEXT_LOOP; + + xtalk_offset_out =3D (uint32_t)(do_division_u(pint->accumulator, pint->c= urrent_samples)); + + itemp32 =3D xtalk_offset_out - current_xtalk + smudge_margin_adjusted; + + if (itemp32 < 0) + itemp32 =3D itemp32 * (-1); + + if (continue_processing =3D=3D CONT_CONTINUE && (itemp32 >=3D ((int32_t)= (pconfig->averaged_xtalk_delta)))) { + if ((int32_t)xtalk_offset_out > ((int32_t)current_xtalk - (int32_t)smud= ge_margin_adjusted)) + pout->averaged_xtalk_delta_flag =3D 1; + else + pout->averaged_xtalk_delta_flag =3D 2; + } + + if (continue_processing =3D=3D CONT_CONTINUE && (itemp32 < ((int32_t)(pc= onfig->averaged_xtalk_delta)))) + continue_processing =3D CONT_RESET; + + pout->smudge_corr_clipped =3D 0; + if ((continue_processing =3D=3D CONT_CONTINUE) && (pconfig->smudge_corr_= clip_limit !=3D 0)) { + if (xtalk_offset_out > (pconfig->smudge_corr_clip_limit * histo_merge_n= b)) { + pout->smudge_corr_clipped =3D 1; + continue_processing =3D CONT_RESET; + } + } + + if (pconfig->user_xtalk_offset_limit_hi && (xtalk_offset_out > pconfig->= user_xtalk_offset_limit)) + xtalk_offset_out =3D pconfig->user_xtalk_offset_limit; + + if ((pconfig->user_xtalk_offset_limit_hi =3D=3D 0) && (xtalk_offset_out = < pconfig->user_xtalk_offset_limit)) + xtalk_offset_out =3D pconfig->user_xtalk_offset_limit; + + xtalk_offset_out =3D xtalk_offset_out >> 2; + if (xtalk_offset_out > 0x3FFFF) + xtalk_offset_out =3D 0x3FFFF; + + if (continue_processing =3D=3D CONT_CONTINUE) { + VL53LX_dynamic_xtalk_correction_calc_new_xtalk(Dev, xtalk_offset_out, p= config, pout, 1, 0); + continue_processing =3D CONT_RESET; + } else { + VL53LX_dynamic_xtalk_correction_calc_new_xtalk(Dev, xtalk_offset_out, p= config, pout, 1, 1); + } + + if (continue_processing =3D=3D CONT_RESET) { + pint->accumulator =3D 0; + pint->current_samples =3D 0; + pint->nodetect_counter =3D 0; + } + } + + continue_processing =3D CONT_CONTINUE; + if (run_nodetect =3D=3D 1) { + pint->nodetect_counter +=3D 1; + if (pint->nodetect_counter < pconfig->nodetect_sample_limit) + continue_processing =3D CONT_NEXT_LOOP; + + xtalk_offset_out =3D (uint32_t)(pconfig->nodetect_xtalk_offset); + + if (continue_processing =3D=3D CONT_CONTINUE) { + VL53LX_dynamic_xtalk_correction_calc_new_xtalk(Dev, xtalk_offset_out, p= config, pout, 0, 0); + pout->smudge_corr_valid =3D 2; + continue_processing =3D CONT_RESET; + } else { + VL53LX_dynamic_xtalk_correction_calc_new_xtalk(Dev, xtalk_offset_out, p= config, pout, 0, 1); + } + + if (continue_processing =3D=3D CONT_RESET) { + pint->accumulator =3D 0; + pint->current_samples =3D 0; + pint->nodetect_counter =3D 0; + } + } + return status; +} + +VL53LX_Error VL53LX_i2c_decode_debug_results(uint16_t buf_size, uint8_t *p= buffer, VL53LX_debug_results_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + pdata->phasecal_result__reference_phase =3D (VL53LX_i2c_decode_uint16_t(2= , pbuffer + 0)); + pdata->phasecal_result__vcsel_start =3D (*(pbuffer + 2)) & 0x7F; + pdata->ref_spad_char_result__num_actual_ref_spads =3D (*(pbuffer + 3)) = & 0x3F; + pdata->ref_spad_char_result__ref_location =3D (*(pbuffer + 4)) & 0x3; + pdata->vhv_result__coldboot_status =3D (*(pbuffer + 5)) & 0x1; + pdata->vhv_result__search_result =3D (*(pbuffer + 6)) & 0x3F; + pdata->vhv_result__latest_setting =3D (*(pbuffer + 7)) & 0x3F; + pdata->result__osc_calibrate_val =3D (VL53LX_i2c_decode_uint16_t(2, pbuff= er + 8)) & 0x3FF; + pdata->ana_config__powerdown_go1 =3D (*(pbuffer + 10)) & 0x3; + pdata->ana_config__ref_bg_ctrl =3D (*(pbuffer + 11)) & 0x3; + pdata->ana_config__regdvdd1v2_ctrl =3D (*(pbuffer + 12)) & 0xF; + pdata->ana_config__osc_slow_ctrl =3D (*(pbuffer + 13)) & 0x7; + pdata->test_mode__status =3D (*(pbuffer + 14)) & 0x1; + pdata->firmware__system_status =3D (*(pbuffer + 15)) & 0x3; + pdata->firmware__mode_status =3D (*(pbuffer + 16)); + pdata->firmware__secondary_mode_status =3D (*(pbuffer + 17)); + pdata->firmware__cal_repeat_rate_counter =3D (VL53LX_i2c_decode_uint16_t(= 2, pbuffer + 18)) & 0xFFF; + pdata->gph__system__thresh_high =3D (VL53LX_i2c_decode_uint16_t(2, pbuffe= r + 22)); + pdata->gph__system__thresh_low =3D (VL53LX_i2c_decode_uint16_t(2, pbuffer= + 24)); + pdata->gph__system__enable_xtalk_per_quadrant =3D (*(pbuffer + 26)) & 0x= 1; + pdata->gph__spare_0 =3D (*(pbuffer + 27)) & 0x7; + pdata->gph__sd_config__woi_sd0 =3D (*(pbuffer + 28)); + pdata->gph__sd_config__woi_sd1 =3D (*(pbuffer + 29)); + pdata->gph__sd_config__initial_phase_sd0 =3D (*(pbuffer + 30)) & 0x7F; + pdata->gph__sd_config__initial_phase_sd1 =3D (*(pbuffer + 31)) & 0x7F; + pdata->gph__sd_config__first_order_select =3D (*(pbuffer + 32)) & 0x3; + pdata->gph__sd_config__quantifier =3D (*(pbuffer + 33)) & 0xF; + pdata->gph__roi_config__user_roi_centre_spad =3D (*(pbuffer + 34)); + pdata->gph__roi_config__user_roi_requested_global_xy_size =3D (*(pbuffer = + 35)); + pdata->gph__system__sequence_config =3D (*(pbuffer + 36)); + pdata->gph__gph_id =3D (*(pbuffer + 37)) & 0x1; + pdata->system__interrupt_set =3D (*(pbuffer + 38)) & 0x3; + pdata->interrupt_manager__enables =3D (*(pbuffer + 39)) & 0x1F; + pdata->interrupt_manager__clear =3D (*(pbuffer + 40)) & 0x1F; + pdata->interrupt_manager__status =3D (*(pbuffer + 41)) & 0x1F; + pdata->mcu_to_host_bank__wr_access_en =3D (*(pbuffer + 42)) & 0x1; + pdata->power_management__go1_reset_status =3D (*(pbuffer + 43)) & 0x1; + pdata->pad_startup_mode__value_ro =3D (*(pbuffer + 44)) & 0x3; + pdata->pad_startup_mode__value_ctrl =3D (*(pbuffer + 45)) & 0x3F; + pdata->pll_period_us =3D (VL53LX_i2c_decode_uint32_t(4, pbuffer + 46)) &= 0x3FFFF; + pdata->interrupt_scheduler__data_out =3D (VL53LX_i2c_decode_uint32_t(4, p= buffer + 50)); + pdata->nvm_bist__complete =3D (*(pbuffer + 54)) & 0x1; + pdata->nvm_bist__status =3D (*(pbuffer + 55)) & 0x1; + + return status; +} + +VL53LX_Error VL53LX_i2c_decode_core_results(uint16_t buf_size, uint8_t *pb= uffer, VL53LX_core_results_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_CORE_RESULTS_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + pdata->result_core__ambient_window_events_sd0 =3D (VL53LX_i2c_decode_uint= 32_t(4, pbuffer + 0)); + pdata->result_core__ranging_total_events_sd0 =3D (VL53LX_i2c_decode_uint3= 2_t(4, pbuffer + 4)); + pdata->result_core__signal_total_events_sd0 =3D (VL53LX_i2c_decode_int32_= t(4, pbuffer + 8)); + pdata->result_core__total_periods_elapsed_sd0 =3D (VL53LX_i2c_decode_uint= 32_t(4, pbuffer + 12)); + pdata->result_core__ambient_window_events_sd1 =3D (VL53LX_i2c_decode_uint= 32_t(4, pbuffer + 16)); + pdata->result_core__ranging_total_events_sd1 =3D (VL53LX_i2c_decode_uint3= 2_t(4, pbuffer + 20)); + pdata->result_core__signal_total_events_sd1 =3D (VL53LX_i2c_decode_int32_= t(4, pbuffer + 24)); + pdata->result_core__total_periods_elapsed_sd1 =3D (VL53LX_i2c_decode_uint= 32_t(4, pbuffer + 28)); + pdata->result_core__spare_0 =3D (*(pbuffer + 32)); + + return status; +} + +VL53LX_Error VL53LX_i2c_decode_system_results(uint16_t buf_size, uint8_t *= pbuffer, VL53LX_system_results_t *pdata) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (buf_size < VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES) + return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL; + + pdata->result__interrupt_status =3D (*(pbuffer + 0)) & 0x3F; + pdata->result__range_status =3D (*(pbuffer + 1)); + pdata->result__report_status =3D (*(pbuffer + 2)) & 0xF; + pdata->result__stream_count =3D (*(pbuffer + 3)); + pdata->result__dss_actual_effective_spads_sd0 =3D (VL53LX_i2c_decode_uint= 16_t(2, pbuffer + 4)); + pdata->result__peak_signal_count_rate_mcps_sd0 =3D (VL53LX_i2c_decode_uin= t16_t(2, pbuffer + 6)); + pdata->result__ambient_count_rate_mcps_sd0 =3D (VL53LX_i2c_decode_uint16_= t(2, pbuffer + 8)); + pdata->result__sigma_sd0 =3D (VL53LX_i2c_decode_uint16_t(2, pbuffer + 10= )); + pdata->result__phase_sd0 =3D (VL53LX_i2c_decode_uint16_t(2, pbuffer + 12= )); + pdata->result__final_crosstalk_corrected_range_mm_sd0 =3D (VL53LX_i2c_dec= ode_uint16_t(2, pbuffer + 14)); + pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 =3D (V= L53LX_i2c_decode_uint16_t(2, pbuffer + 16)); + pdata->result__mm_inner_actual_effective_spads_sd0 =3D (VL53LX_i2c_decode= _uint16_t(2, pbuffer + 18)); + pdata->result__mm_outer_actual_effective_spads_sd0 =3D (VL53LX_i2c_decode= _uint16_t(2, pbuffer + 20)); + pdata->result__avg_signal_count_rate_mcps_sd0 =3D (VL53LX_i2c_decode_uint= 16_t(2, pbuffer + 22)); + pdata->result__dss_actual_effective_spads_sd1 =3D (VL53LX_i2c_decode_uint= 16_t(2, pbuffer + 24)); + pdata->result__peak_signal_count_rate_mcps_sd1 =3D (VL53LX_i2c_decode_uin= t16_t(2, pbuffer + 26)); + pdata->result__ambient_count_rate_mcps_sd1 =3D (VL53LX_i2c_decode_uint16_= t(2, pbuffer + 28)); + pdata->result__sigma_sd1 =3D (VL53LX_i2c_decode_uint16_t(2, pbuffer + 30= )); + pdata->result__phase_sd1 =3D (VL53LX_i2c_decode_uint16_t(2, pbuffer + 32= )); + pdata->result__final_crosstalk_corrected_range_mm_sd1 =3D (VL53LX_i2c_dec= ode_uint16_t(2, pbuffer + 34)); + pdata->result__spare_0_sd1 =3D (VL53LX_i2c_decode_uint16_t(2, pbuffer + = 36)); + pdata->result__spare_1_sd1 =3D (VL53LX_i2c_decode_uint16_t(2, pbuffer + = 38)); + pdata->result__spare_2_sd1 =3D (VL53LX_i2c_decode_uint16_t(2, pbuffer + = 40)); + pdata->result__spare_3_sd1 =3D (*(pbuffer + 42)); + pdata->result__thresh_info =3D (*(pbuffer + 43)); + + return status; +} + +VL53LX_Error VL53LX_get_measurement_results(VL53LX_DEV Dev, VL53LX_DeviceR= esultsLevel device_results_level) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + uint8_t buffer[VL53LX_MAX_I2C_XFER_SIZE]; + VL53LX_system_results_t *psystem_results =3D &(pdev->sys_results); + VL53LX_core_results_t *pcore_results =3D &(pdev->core_results); + VL53LX_debug_results_t *pdebug_results =3D &(pdev->dbg_results); + uint16_t i2c_index =3D VL53LX_SYSTEM_RESULTS_I2C_INDEX; + uint16_t i2c_buffer_offset_bytes =3D 0; + uint16_t i2c_buffer_size_bytes =3D 0; + + switch (device_results_level) { + case VL53LX_DEVICERESULTSLEVEL_FULL: + i2c_buffer_size_bytes =3D (VL53LX_DEBUG_RESULTS_I2C_INDEX + VL53LX_DEBUG= _RESULTS_I2C_SIZE_BYTES) - i2c_index; + break; + case VL53LX_DEVICERESULTSLEVEL_UPTO_CORE: + i2c_buffer_size_bytes =3D (VL53LX_CORE_RESULTS_I2C_INDEX + VL53LX_CORE_R= ESULTS_I2C_SIZE_BYTES) - i2c_index; + break; + default: + i2c_buffer_size_bytes =3D VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES; + break; + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_ReadMulti(Dev, i2c_index, buffer, (uint32_t)i2c_buffer= _size_bytes); + + if (device_results_level >=3D VL53LX_DEVICERESULTSLEVEL_FULL && status = =3D=3D VL53LX_ERROR_NONE) { + i2c_buffer_offset_bytes =3D VL53LX_DEBUG_RESULTS_I2C_INDEX - i2c_index; + status =3D VL53LX_i2c_decode_debug_results(VL53LX_DEBUG_RESULTS_I2C_SIZE= _BYTES, &buffer[i2c_buffer_offset_bytes], pdebug_results); + } + + if (device_results_level >=3D VL53LX_DEVICERESULTSLEVEL_UPTO_CORE && stat= us =3D=3D VL53LX_ERROR_NONE) { + i2c_buffer_offset_bytes =3D VL53LX_CORE_RESULTS_I2C_INDEX - i2c_index; + status =3D VL53LX_i2c_decode_core_results(VL53LX_CORE_RESULTS_I2C_SIZE_B= YTES, &buffer[i2c_buffer_offset_bytes], pcore_results); + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + i2c_buffer_offset_bytes =3D 0; + status =3D VL53LX_i2c_decode_system_results(VL53LX_SYSTEM_RESULTS_I2C_SI= ZE_BYTES, &buffer[i2c_buffer_offset_bytes], psystem_results); + } + + return status; +} + +void VL53LX_copy_sys_and_core_results_to_range_results(int32_t gain_factor= , VL53LX_system_results_t *psys, VL53LX_core_results_t *pcore, VL53LX_range= _results_t *presults) +{ + uint8_t i =3D 0; + VL53LX_range_data_t *pdata; + int32_t range_mm =3D 0; + uint32_t tmpu32 =3D 0; + uint16_t rpscr_crosstalk_corrected_mcps_sd0; + uint16_t rmmo_effective_spads_sd0; + uint16_t rmmi_effective_spads_sd0; + + presults->zone_id =3D 0; + presults->stream_count =3D psys->result__stream_count; + presults->wrap_dmax_mm =3D 0; + presults->max_results =3D VL53LX_MAX_RANGE_RESULTS; + presults->active_results =3D 1; + rpscr_crosstalk_corrected_mcps_sd0 =3D psys->result__peak_signal_count_ra= te_crosstalk_corrected_mcps_sd0; + rmmo_effective_spads_sd0 =3D psys->result__mm_outer_actual_effective_spad= s_sd0; + rmmi_effective_spads_sd0 =3D psys->result__mm_inner_actual_effective_spad= s_sd0; + + for (i =3D 0; i < VL53LX_MAX_AMBIENT_DMAX_VALUES; i++) + presults->VL53LX_p_022[i] =3D 0; + + pdata =3D &(presults->VL53LX_p_003[0]); + + for (i =3D 0; i < 2; i++) { + pdata->range_id =3D i; + pdata->time_stamp =3D 0; + + if ((psys->result__stream_count =3D=3D 0) && ((psys->result__range_statu= s & VL53LX_RANGE_STATUS__RANGE_STATUS_MASK) =3D=3D VL53LX_DEVICEERROR_RANGE= COMPLETE)) { + pdata->range_status =3D VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK; + } else { + pdata->range_status =3D psys->result__range_status & VL53LX_RANGE_STATU= S__RANGE_STATUS_MASK; + } + + pdata->VL53LX_p_012 =3D 0; + pdata->VL53LX_p_019 =3D 0; + pdata->VL53LX_p_023 =3D 0; + pdata->VL53LX_p_024 =3D 0; + pdata->VL53LX_p_013 =3D 0; + pdata->VL53LX_p_025 =3D 0; + + switch (i) { + case 0: + if (psys->result__report_status =3D=3D VL53LX_DEVICEREPORTSTATUS_MM1) + pdata->VL53LX_p_004 =3D rmmi_effective_spads_sd0; + else if (psys->result__report_status =3D=3D VL53LX_DEVICEREPORTSTATUS_M= M2) + pdata->VL53LX_p_004 =3D rmmo_effective_spads_sd0; + else + pdata->VL53LX_p_004 =3D psys->result__dss_actual_effective_spads_sd0; + + pdata->peak_signal_count_rate_mcps =3D rpscr_crosstalk_corrected_mcps_s= d0; + pdata->avg_signal_count_rate_mcps =3D psys->result__avg_signal_count_ra= te_mcps_sd0; + pdata->ambient_count_rate_mcps =3D psys->result__ambient_count_rate_mcp= s_sd0; + + tmpu32 =3D ((uint32_t)psys->result__sigma_sd0 << 5); + if (tmpu32 > 0xFFFF) + tmpu32 =3D 0xFFFF; + pdata->VL53LX_p_002 =3D (uint16_t)tmpu32; + pdata->VL53LX_p_011 =3D psys->result__phase_sd0; + + range_mm =3D (int32_t)(psys->result__final_crosstalk_corrected_range_mm= _sd0); + range_mm *=3D gain_factor; + range_mm +=3D 0x0400; + range_mm /=3D 0x0800; + + pdata->median_range_mm =3D (int16_t)range_mm; + pdata->VL53LX_p_017 =3D pcore->result_core__ranging_total_events_sd0; + pdata->VL53LX_p_010 =3D pcore->result_core__si= gnal_total_events_sd0; + pdata->total_periods_elapsed =3D pcore->result_core__total_periods_elap= sed_sd0; + pdata->VL53LX_p_016 =3D pcore->result_core__ambient_window_events_sd0; + break; + case 1: + pdata->VL53LX_p_004 =3D psys->result__dss_actual_effective_spads_sd1; + pdata->peak_signal_count_rate_mcps =3D psys->result__peak_signal_count_= rate_mcps_sd1; + pdata->avg_signal_count_rate_mcps =3D 0xFFFF; + pdata->ambient_count_rate_mcps =3D psys->result__ambient_count_rate_mcp= s_sd1; + + tmpu32 =3D ((uint32_t)psys->result__sigma_sd1 << 5); + if (tmpu32 > 0xFFFF) + tmpu32 =3D 0xFFFF; + pdata->VL53LX_p_002 =3D (uint16_t)tmpu32; + pdata->VL53LX_p_011 =3D psys->result__phase_sd1; + + range_mm =3D (int32_t)(psys->result__final_crosstalk_corrected_range_mm= _sd1); + range_mm *=3D gain_factor; + range_mm +=3D 0x0400; + range_mm /=3D 0x0800; + + pdata->median_range_mm =3D (int16_t)range_mm; + pdata->VL53LX_p_017 =3D pcore->result_core__ranging_total_events_sd1; + pdata->VL53LX_p_010 =3D pcore->result_core__signal_total_events_sd1; + pdata->total_periods_elapsed =3D pcore->result_core__total_periods_ela= psed_sd1; + pdata->VL53LX_p_016 =3D pcore->result_core__ambient_window_events_sd1; + break; + } + + pdata->VL53LX_p_026 =3D pdata->VL53LX_p_011; + pdata->VL53LX_p_027 =3D pdata->VL53LX_p_011; + pdata->min_range_mm =3D pdata->median_range_mm; + pdata->max_range_mm =3D pdata->median_range_mm; + pdata++; + } + + presults->device_status =3D VL53LX_DEVICEERROR_NOUPDATE; + + switch (psys->result__range_status & VL53LX_RANGE_STATUS__RANGE_STATUS_MA= SK) { + case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE: + case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE: + case VL53LX_DEVICEERROR_NOVHVVALUEFOUND: + case VL53LX_DEVICEERROR_USERROICLIP: + case VL53LX_DEVICEERROR_MULTCLIPFAIL: + presults->device_status =3D (psys->result__range_status & VL53LX_RANGE_S= TATUS__RANGE_STATUS_MASK); + presults->VL53LX_p_003[0].range_status =3D VL53LX_DEVICEERROR_NOUPDATE; + break; + } +} + +VL53LX_Error VL53LX_low_power_auto_setup_manual_calibration(VL53LX_DEV Dev) +{ + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pdev->low_power_auto_data.saved_vhv_init =3D pdev->stat_nvm.vhv_config__i= nit; + pdev->low_power_auto_data.saved_vhv_timeout =3D pdev->stat_nvm.vhv_config= __timeout_macrop_loop_bound; + pdev->stat_nvm.vhv_config__init &=3D 0x7F; + pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =3D (pdev->stat_nvm.= vhv_config__timeout_macrop_loop_bound & 0x03) + (pdev->low_power_auto_data.= vhv_loop_bound << 2); + pdev->gen_cfg.phasecal_config__override =3D 0x01; + pdev->low_power_auto_data.first_run_phasecal_result =3D pdev->dbg_results= .phasecal_result__vcsel_start; + pdev->gen_cfg.cal_config__vcsel_start =3D pdev->low_power_auto_data.first= _run_phasecal_result; + + return status; +} + +VL53LX_Error VL53LX_low_power_auto_update_DSS(VL53LX_DEV Dev) +{ + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_system_results_t *pS =3D &(pdev->sys_results); + VL53LX_Error status =3D VL53LX_ERROR_NONE; + uint32_t utemp32a; + + utemp32a =3D pS->result__peak_signal_count_rate_crosstalk_corrected_mcps_= sd0 + pS->result__ambient_count_rate_mcps_sd0; + + if (utemp32a > 0xFFFF) + utemp32a =3D 0xFFFF; + + utemp32a =3D utemp32a << 16; + + if (pdev->sys_results.result__dss_actual_effective_spads_sd0 =3D=3D 0) + status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + else { + utemp32a =3D utemp32a / + pdev->sys_results.result__dss_actual_effective_spads_sd0; + pdev->low_power_auto_data.dss__total_rate_per_spad_mcps =3D utemp32a; + utemp32a =3D pdev->stat_cfg.dss_config__target_total_rate_mcps << 16; + if (pdev->low_power_auto_data.dss__total_rate_per_spad_mcps =3D=3D 0) + status =3D VL53LX_ERROR_DIVISION_BY_ZERO; + else { + utemp32a =3D utemp32a / pdev->low_power_auto_data.dss__total_rate_per_s= pad_mcps; + + if (utemp32a > 0xFFFF) + utemp32a =3D 0xFFFF; + + pdev->low_power_auto_data.dss__required_spads =3D (uint16_t)utemp32a; + pdev->gen_cfg.dss_config__manual_effective_spads_select =3D pdev->low_p= ower_auto_data.dss__required_spads; + pdev->gen_cfg.dss_config__roi_mode_control =3D VL53LX_DEVICEDSSMODE__RE= QUESTED_EFFFECTIVE_SPADS; + } + } + + if (status =3D=3D VL53LX_ERROR_DIVISION_BY_ZERO) { + pdev->low_power_auto_data.dss__required_spads =3D 0x8000; + pdev->gen_cfg.dss_config__manual_effective_spads_select =3D pdev->low_po= wer_auto_data.dss__required_spads; + pdev->gen_cfg.dss_config__roi_mode_control =3D VL53LX_DEVICEDSSMODE__REQ= UESTED_EFFFECTIVE_SPADS; + status =3D VL53LX_ERROR_NONE; + } + + return status; +} + +VL53LX_Error VL53LX_check_ll_driver_rd_state(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev= ); + VL53LX_ll_driver_state_t *pstate =3D &(pdev->ll_state); + VL53LX_system_results_t *psys_results =3D &(pdev->sys_results); + VL53LX_histogram_bin_data_t *phist_data =3D &(pdev->hist_data); + VL53LX_zone_private_dyn_cfgs_t *pZ =3D &(pres->zone_dyn_cfgs); + + uint8_t device_range_status =3D 0; + uint8_t device_stream_count =3D 0; + uint8_t device_gph_id =3D 0; + uint8_t histogram_mode =3D 0; + uint8_t expected_stream_count =3D 0; + uint8_t expected_gph_id =3D 0; + + device_range_status =3D psys_results->result__range_status & VL53LX_RANGE= _STATUS__RANGE_STATUS_MASK; + device_stream_count =3D psys_results->result__stream_count; + + histogram_mode =3D (pdev->sys_ctrl.system__mode_start & VL53LX_DEVICESCHE= DULERMODE_HISTOGRAM) =3D=3D VL53LX_DEVICESCHEDULERMODE_HISTOGRAM; + + device_gph_id =3D (psys_results->result__interrupt_status & VL53LX_INTERR= UPT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4; + + if (histogram_mode) + device_gph_id =3D (phist_data->result__interrupt_status & VL53LX_INTERRU= PT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4; + + if (!((pdev->sys_ctrl.system__mode_start & VL53LX_DEVICEMEASUREMENTMODE_B= ACKTOBACK) =3D=3D VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK)) + goto ENDFUNC; + + if (pstate->rd_device_state =3D=3D VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SY= NC) { + if (histogram_mode =3D=3D 0) { + if (device_range_status !=3D VL53LX_DEVICEERROR_GPHSTREAMCOUNT0READY) + status =3D VL53LX_ERROR_GPH_SYNC_CHECK_FAIL; + } + } else { + if (pstate->rd_stream_count !=3D device_stream_count) + status =3D VL53LX_ERROR_STREAM_COUNT_CHECK_FAIL; + + if (pstate->rd_gph_id !=3D device_gph_id) + status =3D VL53LX_ERROR_GPH_ID_CHECK_FAIL; + + expected_stream_count =3D pZ->VL53LX_p_003[pstate->rd_zone_id].expected_= stream_count; + expected_gph_id =3D pZ->VL53LX_p_003[pstate->rd_zone_id].expected_gph_id; + + if (expected_stream_count !=3D device_stream_count) { + if (!((pdev->zone_cfg.active_zones =3D=3D 0) && (device_stream_count = =3D=3D 255))) + status =3D VL53LX_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL; + } + + if (expected_gph_id !=3D device_gph_id) + status =3D VL53LX_ERROR_ZONE_GPH_ID_CHECK_FAIL; + } + +ENDFUNC: + return status; +} + +VL53LX_Error VL53LX_get_device_results(VL53LX_DEV Dev, VL53LX_DeviceResult= sLevel device_results_level, VL53LX_range_results_t *prange_results) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_LLDriverResults_t *pres =3D VL53LXDevStructGetLLResultsHandle(Dev); + VL53LX_range_results_t *presults =3D &(pres->range_results); + VL53LX_zone_objects_t *pobjects =3D &(pres->zone_results.VL53LX_p_003[0]); + VL53LX_ll_driver_state_t *pstate =3D &(pdev->ll_state); + VL53LX_zone_config_t *pzone_cfg =3D &(pdev->zone_cfg); + VL53LX_zone_hist_info_t *phist_info =3D &(pres->zone_hists.VL53LX_p_003[0= ]); + VL53LX_dmax_calibration_data_t dmax_cal; + VL53LX_dmax_calibration_data_t *pdmax_cal =3D &dmax_cal; + VL53LX_hist_post_process_config_t *pHP =3D &(pdev->histpostprocess); + VL53LX_xtalk_config_t *pC =3D &(pdev->xtalk_cfg); + VL53LX_low_power_auto_data_t *pL =3D &(pdev->low_power_auto_data); + VL53LX_histogram_bin_data_t *pHD =3D &(pdev->hist_data); + VL53LX_customer_nvm_managed_t *pN =3D &(pdev->customer); + VL53LX_zone_histograms_t *pZH =3D &(pres->zone_hists); + VL53LX_xtalk_calibration_results_t *pXCR =3D &(pdev->xtalk_cal); + uint8_t tmp8; + uint8_t zid; + uint8_t i; + uint8_t histo_merge_nb, idx; + VL53LX_range_data_t *pdata; + + if ((pdev->sys_ctrl.system__mode_start & VL53LX_DEVICESCHEDULERMODE_HISTO= GRAM) =3D=3D VL53LX_DEVICESCHEDULERMODE_HISTOGRAM) { + status =3D VL53LX_get_histogram_bin_data(Dev, &(pdev->hist_data)); + if (status =3D=3D VL53LX_ERROR_NONE && + pHD->number_of_ambient_bins =3D=3D 0) { + zid =3D pdev->ll_state.rd_zone_id; + status =3D VL53LX_hist_copy_and_scale_ambient_info(&(pZH->VL53LX_p_003[= zid]), &(pdev->hist_data)); + } + if (status !=3D VL53LX_ERROR_NONE) + goto UPDATE_DYNAMIC_CONFIG; + + VL53LX_compute_histo_merge_nb(Dev, &histo_merge_nb); + if (histo_merge_nb =3D=3D 0) + histo_merge_nb =3D 1; + idx =3D histo_merge_nb - 1; + if (pdev->tuning_parms.tp_hist_merge =3D=3D 1) + pC->algo__crosstalk_compensation_plane_offset_kcps =3D pXCR->algo__xtal= k_cpo_HistoMerge_kcps[idx]; + + pHP->gain_factor =3D pdev->gain_cal.histogram_ranging_gain_factor; + + pHP->algo__crosstalk_compensation_plane_offset_kcps =3D VL53LX_calc_cros= stalk_plane_offset_with_margin(pC->algo__crosstalk_compensation_plane_offse= t_kcps, pC->histogram_mode_crosstalk_margin_kcps); + + pHP->algo__crosstalk_compensation_x_plane_gradient_kcps =3D pC->algo__cr= osstalk_compensation_x_plane_gradient_kcps; + pHP->algo__crosstalk_compensation_y_plane_gradient_kcps =3D pC->algo__cr= osstalk_compensation_y_plane_gradient_kcps; + + pdev->dmax_cfg.ambient_thresh_sigma =3D pHP->ambient_thresh_sigma1; + pdev->dmax_cfg.min_ambient_thresh_events =3D pHP->min_ambient_thresh_eve= nts; + pdev->dmax_cfg.signal_total_events_limit =3D pHP->signal_total_events_li= mit; + pdev->dmax_cfg.dss_config__target_total_rate_mcps =3D pdev->stat_cfg.dss= _config__target_total_rate_mcps; + pdev->dmax_cfg.dss_config__aperture_attenuation =3D pdev->gen_cfg.dss_co= nfig__aperture_attenuation; + + pHP->algo__crosstalk_detect_max_valid_range_mm =3D pC->algo__crosstalk_d= etect_max_valid_range_mm; + pHP->algo__crosstalk_detect_min_valid_range_mm =3D pC->algo__crosstalk_d= etect_min_valid_range_mm; + pHP->algo__crosstalk_detect_max_valid_rate_kcps =3D pC->algo__crosstalk_= detect_max_valid_rate_kcps; + pHP->algo__crosstalk_detect_max_sigma_mm =3D pC->algo__crosstalk_detect_= max_sigma_mm; + + VL53LX_copy_rtn_good_spads_to_buffer(&(pdev->nvm_copy_data), &(pdev->rtn= _good_spads[0])); + + switch (pdev->offset_correction_mode) { + case VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS: + tmp8 =3D pdev->gen_cfg.dss_config__aperture_attenuation; + VL53LX_hist_combine_mm1_mm2_offsets( + pN->mm_config__inner_offset_mm, + pN->mm_config__outer_offset_mm, + pdev->nvm_copy_data.roi_config__mode_roi_centre_spad, + pdev->nvm_copy_data.roi_config__mode_roi_xy_size, + pHD->roi_config__user_roi_centre_spad, + pHD->roi_config__user_roi_requested_global_xy_size, + &(pdev->add_off_cal_data), + &(pdev->rtn_good_spads[0]), + (uint16_t)tmp8, + &(pHP->range_offset_mm)); + break; + case VL53LX_OFFSETCORRECTIONMODE__PER_VCSEL_OFFSETS: + select_offset_per_vcsel(pdev, &(pHP->range_offset_mm)); + pHP->range_offset_mm *=3D 4; + break; + default: + pHP->range_offset_mm =3D 0; + break; + } + + if (status !=3D VL53LX_ERROR_NONE) + goto UPDATE_DYNAMIC_CONFIG; + + VL53LX_calc_max_effective_spads( + pHD->roi_config__user_roi_centre_spad, + pHD->roi_config__user_roi_requested_global_xy_size, + &(pdev->rtn_good_spads[0]), + (uint16_t)pdev->gen_cfg.dss_config__aperture_attenuation, + &(pdev->dmax_cfg.max_effective_spads)); + + status =3D VL53LX_get_dmax_calibration_data(Dev, pdev->dmax_mode, pdmax_= cal); + + if (status !=3D VL53LX_ERROR_NONE) + goto UPDATE_DYNAMIC_CONFIG; + + status =3D VL53LX_ipp_hist_process_data( + Dev, + pdmax_cal, + &(pdev->dmax_cfg), + &(pdev->histpostprocess), + &(pdev->hist_data), + &(pdev->xtalk_shapes), + pdev->wArea1, + pdev->wArea2, + &histo_merge_nb, + presults); + + if ((pdev->tuning_parms.tp_hist_merge =3D=3D 1) && + (histo_merge_nb > 1)) + for (i =3D 0; i < VL53LX_MAX_RANGE_RESULTS; i++) { + pdata =3D &(presults->VL53LX_p_003[i]); + pdata->VL53LX_p_016 /=3D histo_merge_nb; + pdata->VL53LX_p_017 /=3D histo_merge_nb; + pdata->VL53LX_p_010 /=3D histo_merge_nb; + pdata->peak_signal_count_rate_mcps /=3D histo_merge_nb; + pdata->avg_signal_count_rate_mcps /=3D histo_merge_nb; + pdata->ambient_count_rate_mcps /=3D histo_merge_nb; + pdata->VL53LX_p_009 /=3D histo_merge_nb; + } + + if (status !=3D VL53LX_ERROR_NONE) + goto UPDATE_DYNAMIC_CONFIG; + + status =3D VL53LX_hist_wrap_dmax(&(pdev->histpostprocess), &(pdev->hist_= data), &(presults->wrap_dmax_mm)); + + if (status !=3D VL53LX_ERROR_NONE) + goto UPDATE_DYNAMIC_CONFIG; + + zid =3D pdev->ll_state.rd_zone_id; + status =3D VL53LX_hist_phase_consistency_check(Dev, &(pZH->VL53LX_p_003[= zid]), &(pres->zone_results.VL53LX_p_003[zid]), presults); + + if (status !=3D VL53LX_ERROR_NONE) + goto UPDATE_DYNAMIC_CONFIG; + + zid =3D pdev->ll_state.rd_zone_id; + status =3D VL53LX_hist_xmonitor_consistency_check(Dev, &(pZH->VL53LX_p_0= 03[zid]), &(pres->zone_results.VL53LX_p_003[zid]), &(presults->xmonitor)); + + if (status !=3D VL53LX_ERROR_NONE) + goto UPDATE_DYNAMIC_CONFIG; + + zid =3D pdev->ll_state.rd_zone_id; + pZH->max_zones =3D VL53LX_MAX_USER_ZONES; + pZH->active_zones =3D pdev->zone_cfg.active_zones+1; + pHD->zone_id =3D zid; + + if (zid < pres->zone_results.max_zones) { + phist_info =3D &(pZH->VL53LX_p_003[zid]); + phist_info->rd_device_state =3D pHD->rd_device_state; + phist_info->number_of_ambient_bins =3D pHD->number_of_ambient_bins; + phist_info->result__dss_actual_effective_spads =3D pHD->result__dss_act= ual_effective_spads; + phist_info->VL53LX_p_005 =3D pHD->VL53LX_p_005; + phist_info->total_periods_elapsed =3D pHD->total_periods_elapsed; + phist_info->ambient_events_sum =3D pHD->ambient_events_sum; + } + + if (status !=3D VL53LX_ERROR_NONE) + goto UPDATE_DYNAMIC_CONFIG; + VL53LX_hist_copy_results_to_sys_and_core(&(pdev->hist_data), presults, &= (pdev->sys_results), &(pdev->core_results)); + +UPDATE_DYNAMIC_CONFIG: + if (pzone_cfg->active_zones > 0) { + if (pstate->rd_device_state !=3D VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SY= NC) { + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_dynamic_zone_update(Dev, presults); + } + } + + for (i =3D 0; i < VL53LX_MAX_USER_ZONES; i++) { + pzone_cfg->bin_config[i] =3D ((pdev->ll_state.cfg_internal_stream_coun= t) & 0x01) ? VL53LX_ZONECONFIG_BINCONFIG__HIGHAMB : VL53LX_ZONECONFIG_BINCO= NFIG__LOWAMB; + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_multizone_hist_bins_update(Dev); + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_dynamic_xtalk_correction_corrector(Dev); + + if (pdev->tuning_parms.tp_hist_merge =3D=3D 1) + pC->algo__crosstalk_compensation_plane_offset_kcps =3D pXCR->algo__xtal= k_cpo_HistoMerge_kcps[0]; + } else { + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_get_measurement_results(Dev, device_results_level); + + if (status =3D=3D VL53LX_ERROR_NONE) + VL53LX_copy_sys_and_core_results_to_range_results((int32_t)pdev->gain_c= al.standard_ranging_gain_factor, &(pdev->sys_results), &(pdev->core_results= ), presults); + + if (pL->is_low_power_auto_mode =3D=3D 1) { + if ((status =3D=3D VL53LX_ERROR_NONE) && (pL->low_power_auto_range_coun= t =3D=3D 0)) { + status =3D VL53LX_low_power_auto_setup_manual_calibration(Dev); + pL->low_power_auto_range_count =3D 1; + } else if ((status =3D=3D VL53LX_ERROR_NONE) && (pL->low_power_auto_ran= ge_count =3D=3D 1)) { + pL->low_power_auto_range_count =3D 2; + } + + if ((pL->low_power_auto_range_count !=3D 0xFF) && (status =3D=3D VL53LX= _ERROR_NONE)) { + status =3D VL53LX_low_power_auto_update_DSS(Dev); + } + } + } + + presults->cfg_device_state =3D pdev->ll_state.cfg_device_state; + presults->rd_device_state =3D pdev->ll_state.rd_device_state; + presults->zone_id =3D pdev->ll_state.rd_zone_id; + + if (status =3D=3D VL53LX_ERROR_NONE) { + pres->zone_results.max_zones =3D VL53LX_MAX_USER_ZONES; + pres->zone_results.active_zones =3D pdev->zone_cfg.active_zones+1; + zid =3D pdev->ll_state.rd_zone_id; + + if (zid < pres->zone_results.max_zones) { + pobjects =3D &(pres->zone_results.VL53LX_p_003[zid]); + pobjects->cfg_device_state =3D presults->cfg_device_state; + pobjects->rd_device_state =3D presults->rd_device_state; + pobjects->zone_id =3D presults->zone_id; + pobjects->stream_count =3D presults->stream_count; + + pobjects->xmonitor.VL53LX_p_016 =3D presults->xmonitor.VL53LX_p_016; + pobjects->xmonitor.VL53LX_p_017 =3D presults->xmonitor.VL53LX_p_017; + pobjects->xmonitor.VL53LX_p_011 =3D presults->xmonitor.VL53LX_p_011; + pobjects->xmonitor.range_status =3D presults->xmonitor.range_status; + + pobjects->max_objects =3D presults->max_results; + pobjects->active_objects =3D presults->active_results; + + for (i =3D 0; i < presults->active_results; i++) { + pobjects->VL53LX_p_003[i].VL53LX_p_016 =3D presults->VL53LX_p_003[i].V= L53LX_p_016; + pobjects->VL53LX_p_003[i].VL53LX_p_017 =3D presults->VL53LX_p_003[i].V= L53LX_p_017; + pobjects->VL53LX_p_003[i].VL53LX_p_011 =3D presults->VL53LX_p_003[i].V= L53LX_p_011; + pobjects->VL53LX_p_003[i].range_status =3D presults->VL53LX_p_003[i].r= ange_status; + } + } + } + + memcpy(prange_results, presults, sizeof(VL53LX_range_results_t)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_check_ll_driver_rd_state(Dev); + return status; +} + +static uint8_t ConvertStatusHisto(uint8_t FilteredRangeStatus) +{ + uint8_t RangeStatus; + + switch (FilteredRangeStatus) { + case VL53LX_DEVICEERROR_RANGEPHASECHECK: + RangeStatus =3D VL53LX_RANGESTATUS_OUTOFBOUNDS_FAIL; + break; + case VL53LX_DEVICEERROR_SIGMATHRESHOLDCHECK: + RangeStatus =3D VL53LX_RANGESTATUS_SIGMA_FAIL; + break; + case VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK: + RangeStatus =3D VL53LX_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL; + break; + case VL53LX_DEVICEERROR_PHASECONSISTENCY: + RangeStatus =3D VL53LX_RANGESTATUS_WRAP_TARGET_FAIL; + break; + case VL53LX_DEVICEERROR_PREV_RANGE_NO_TARGETS: + RangeStatus =3D VL53LX_RANGESTATUS_TARGET_PRESENT_LACK_OF_SIGNAL; + break; + case VL53LX_DEVICEERROR_EVENTCONSISTENCY: + RangeStatus =3D VL53LX_RANGESTATUS_WRAP_TARGET_FAIL; + break; + case VL53LX_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE: + RangeStatus =3D VL53LX_RANGESTATUS_RANGE_VALID_MERGED_PULSE; + break; + case VL53LX_DEVICEERROR_RANGECOMPLETE: + RangeStatus =3D VL53LX_RANGESTATUS_RANGE_VALID; + break; + default: + RangeStatus =3D VL53LX_RANGESTATUS_NONE; + } + return RangeStatus; +} + +static VL53LX_Error SetTargetData(VL53LX_DEV Dev, + uint8_t active_results, uint8_t streamcount, uint8_t iteration, + uint8_t device_status, VL53LX_range_data_t *presults_data, + VL53LX_TargetRangeData_t *pRangeData) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_tuning_parm_storage_t *tp =3D &(pdev->tuning_parms); + uint8_t sequency; + uint8_t FilteredRangeStatus; + FixPoint1616_t AmbientRate; + FixPoint1616_t SignalRate; + FixPoint1616_t TempFix1616; + int16_t Range, RangeDiff, RangeMillimeterInit; + int32_t ExtendedRangeEnabled =3D 0; + uint8_t uwr_status; + int16_t AddOffset; + + SUPPRESS_UNUSED_WARNING(Dev); + + FilteredRangeStatus =3D presults_data->range_status & 0x1F; + + SignalRate =3D VL53LX_FIXPOINT97TOFIXPOINT1616(presults_data->peak_signal= _count_rate_mcps); + pRangeData->SignalRateRtnMegaCps =3D SignalRate; + + AmbientRate =3D VL53LX_FIXPOINT97TOFIXPOINT1616(presults_data->ambient_co= unt_rate_mcps); + pRangeData->AmbientRateRtnMegaCps =3D AmbientRate; + + TempFix1616 =3D VL53LX_FIXPOINT97TOFIXPOINT1616(presults_data->VL53LX_p_0= 02); + + pRangeData->SigmaMilliMeter =3D TempFix1616; + + pRangeData->RangeMilliMeter =3D presults_data->median_range_mm; + pRangeData->RangeMaxMilliMeter =3D presults_data->max_range_mm; + pRangeData->RangeMinMilliMeter =3D presults_data->min_range_mm; + + switch (device_status) { + case VL53LX_DEVICEERROR_MULTCLIPFAIL: + case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE: + case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE: + case VL53LX_DEVICEERROR_NOVHVVALUEFOUND: + pRangeData->RangeStatus =3D VL53LX_RANGESTATUS_HARDWARE_FAIL; + break; + case VL53LX_DEVICEERROR_USERROICLIP: + pRangeData->RangeStatus =3D VL53LX_RANGESTATUS_MIN_RANGE_FAIL; + break; + default: + pRangeData->RangeStatus =3D VL53LX_RANGESTATUS_RANGE_VALID; + } + + if ((pRangeData->RangeStatus =3D=3D VL53LX_RANGESTATUS_RANGE_VALID) && (= active_results =3D=3D 0)) { + pRangeData->RangeStatus =3D VL53LX_RANGESTATUS_NONE; + pRangeData->SignalRateRtnMegaCps =3D 0; + pRangeData->SigmaMilliMeter =3D 0; + pRangeData->RangeMilliMeter =3D 8191; + pRangeData->RangeMaxMilliMeter =3D 8191; + pRangeData->RangeMinMilliMeter =3D 8191; + } + + if (pRangeData->RangeStatus =3D=3D VL53LX_RANGESTATUS_RANGE_VALID) + pRangeData->RangeStatus =3D ConvertStatusHisto(FilteredRangeStatus); + + VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_UWR_ENABLE, &ExtendedRangeE= nabled); + + sequency =3D streamcount % 2; + uwr_status =3D 0; + RangeMillimeterInit =3D pRangeData->RangeMilliMeter; + AddOffset =3D 0; + + pRangeData->ExtendedRange =3D 0; + + if ((active_results !=3D 1) || (pdev->PreviousRangeActiveResults !=3D 1)) + ExtendedRangeEnabled =3D 0; + + if (ExtendedRangeEnabled && + (pRangeData->RangeStatus =3D=3D + VL53LX_RANGESTATUS_WRAP_TARGET_FAIL || + pRangeData->RangeStatus =3D=3D + VL53LX_RANGESTATUS_OUTOFBOUNDS_FAIL) + && (pdev->PreviousRangeStatus[iteration] =3D=3D + VL53LX_RANGESTATUS_WRAP_TARGET_FAIL || + pdev->PreviousRangeStatus[iteration] =3D=3D + VL53LX_RANGESTATUS_OUTOFBOUNDS_FAIL || + (pdev->PreviousRangeStatus[iteration] =3D=3D + VL53LX_RANGESTATUS_RANGE_VALID && + pdev->PreviousExtendedRange[iteration] =3D=3D 1))) { + if (((pdev->PreviousStreamCount) =3D=3D (pdev->hist_data.result__stream_= count - 1)) || ((pdev->PreviousStreamCount) =3D=3D (pdev->hist_data.result_= _stream_count + 127))) { + RangeDiff =3D pRangeData->RangeMilliMeter - pdev->PreviousRangeMilliMet= er[iteration]; + uwr_status =3D 1; + switch (pdev->preset_mode) { + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE: + uwr_status =3D 0; + break; + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE: + if (RangeDiff > tp->tp_uwr_med_z_1_min && RangeDiff < tp->tp_uwr_med_z= _1_max && sequency =3D=3D 1) { + AddOffset =3D + tp->tp_uwr_med_corr_z_1_rangeb; + } else if (RangeDiff < -tp->tp_uwr_med_z_1_min && RangeDiff > -tp->tp_= uwr_med_z_1_max && sequency =3D=3D 0) { + AddOffset =3D tp->tp_uwr_med_corr_z_1_rangea; + } else if (RangeDiff > tp->tp_uwr_med_z_2_min && RangeDiff < tp->tp_uw= r_med_z_2_max && sequency =3D=3D 0) { + AddOffset =3D tp->tp_uwr_med_corr_z_2_rangea; + } else if (RangeDiff < -tp->tp_uwr_med_z_2_min && RangeDiff > -tp->tp_= uwr_med_z_2_max && sequency =3D=3D 1) { + AddOffset =3D tp->tp_uwr_med_corr_z_2_rangeb; + } else if (RangeDiff > tp->tp_uwr_med_z_3_min && RangeDiff < tp->tp_uw= r_med_z_3_max && sequency =3D=3D 1) { + AddOffset =3D tp->tp_uwr_med_corr_z_3_rangeb; + } else if (RangeDiff < -tp->tp_uwr_med_z_3_min && RangeDiff > -tp->tp_= uwr_med_z_3_max && sequency =3D=3D 0) { + AddOffset =3D tp->tp_uwr_med_corr_z_3_rangea; + } else if (RangeDiff > tp->tp_uwr_med_z_4_min && RangeDiff < tp->tp_uw= r_med_z_4_max && sequency =3D=3D 0) { + AddOffset =3D tp->tp_uwr_med_corr_z_4_rangea; + } else if (RangeDiff < -tp->tp_uwr_med_z_4_min && RangeDiff > -tp->tp_= uwr_med_z_4_max && sequency =3D=3D 1) { + AddOffset =3D tp->tp_uwr_med_corr_z_4_rangeb; + } else if (RangeDiff < tp->tp_uwr_med_z_5_max && RangeDiff > tp->tp_uw= r_med_z_5_min) { + AddOffset =3D tp->tp_uwr_med_corr_z_5_rangea; + } else + uwr_status =3D 0; + break; + case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE: + if (RangeDiff > tp->tp_uwr_lng_z_1_min && RangeDiff < tp->tp_uwr_lng_z= _1_max && sequency =3D=3D 0) { + AddOffset =3D tp->tp_uwr_lng_corr_z_1_rangea; + } else if (RangeDiff < -tp->tp_uwr_lng_z_1_min && RangeDiff > -tp->tp_= uwr_lng_z_1_max && sequency =3D=3D 1) { + AddOffset =3D tp->tp_uwr_lng_corr_z_1_rangeb; + } else if (RangeDiff > tp->tp_uwr_lng_z_2_min && RangeDiff < tp->tp_uw= r_lng_z_2_max && sequency =3D=3D 1) { + AddOffset =3D tp->tp_uwr_lng_corr_z_2_rangeb; + } else if (RangeDiff < -tp->tp_uwr_lng_z_2_min && RangeDiff > -tp->tp_= uwr_lng_z_2_max && sequency =3D=3D 0) { + AddOffset =3D tp->tp_uwr_lng_corr_z_2_rangea; + } else if (RangeDiff < tp->tp_uwr_lng_z_3_max && RangeDiff > tp->tp_uw= r_lng_z_3_min) { + AddOffset =3D tp->tp_uwr_lng_corr_z_3_rangea; + } else + uwr_status =3D 0; + break; + default: + uwr_status =3D 0; + break; + } + } + + if (uwr_status) { + pRangeData->RangeMilliMeter +=3D AddOffset; + pRangeData->RangeMinMilliMeter +=3D AddOffset; + pRangeData->RangeMaxMilliMeter +=3D AddOffset; + pRangeData->ExtendedRange =3D 1; + pRangeData->RangeStatus =3D 0; + } + + } + + pdev->PreviousRangeMilliMeter[iteration] =3D RangeMillimeterInit; + pdev->PreviousRangeStatus[iteration] =3D pRangeData->RangeStatus; + pdev->PreviousExtendedRange[iteration] =3D pRangeData->ExtendedRange; + pdev->PreviousRangeActiveResults =3D active_results; + + Range =3D pRangeData->RangeMilliMeter; + if ((pRangeData->RangeStatus =3D=3D VL53LX_RANGESTATUS_RANGE_VALID) && (= Range < 0)) { + if (Range < BDTable[VL53LX_TUNING_PROXY_MIN]) + pRangeData->RangeStatus =3D VL53LX_RANGESTATUS_RANGE_INVALID; + else + pRangeData->RangeMilliMeter =3D 0; + } + + return Status; +} + +static VL53LX_Error SetMeasurementData(VL53LX_DEV Dev, VL53LX_range_result= s_t *presults, VL53LX_MultiRangingData_t *pMultiRangingData) +{ + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + uint8_t i; + uint8_t iteration; + VL53LX_TargetRangeData_t *pRangeData; + VL53LX_range_data_t *presults_data; + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + uint8_t ActiveResults; + + pMultiRangingData->NumberOfObjectsFound =3D presults->active_results; + pMultiRangingData->HasXtalkValueChanged =3D presults->smudge_corrector_da= ta.new_xtalk_applied_flag; + + pMultiRangingData->TimeStamp =3D 0; + + pMultiRangingData->StreamCount =3D presults->stream_count; + + ActiveResults =3D presults->active_results; + if (ActiveResults < 1) + iteration =3D 1; + else + iteration =3D ActiveResults; + for (i =3D 0; i < iteration; i++) { + pRangeData =3D &(pMultiRangingData->RangeData[i]); + presults_data =3D &(presults->VL53LX_p_003[i]); + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D SetTargetData(Dev, ActiveResults, pMultiRangingData->StreamC= ount, i, presults->device_status, presults_data, pRangeData); + + pMultiRangingData->EffectiveSpadRtnCount =3D presults_data->VL53LX_p_004; + } + pdev->PreviousStreamCount =3D pdev->hist_data.result__stream_count; + for (i =3D iteration; i < VL53LX_MAX_RANGE_RESULTS; i++) { + pdev->PreviousRangeMilliMeter[i] =3D 0; + pdev->PreviousRangeStatus[i] =3D 255; + pdev->PreviousExtendedRange[i] =3D 0; + } + + return Status; +} + +static void stmvl53lx_work_handler(struct work_struct *work) +{ + struct stmvl53lx_data *data; + + data =3D container_of(work, struct stmvl53lx_data, dwork.work); + work_dbg("enter"); + mutex_lock(&data->work_mutex); + stmvl53lx_intr_process(data); + if (data->poll_mode && data->enable_sensor) { + schedule_delayed_work(&data->dwork, msecs_to_jiffies(data->poll_delay_ms= )); + } + mutex_unlock(&data->work_mutex); +} + +static int ctrl_roi(struct stmvl53lx_data *data, void __user *p) +{ + int rc; + struct stmvl53lx_ioctl_roi_t roi; + + mutex_lock(&data->work_mutex); + + if (data->is_device_remove) { + rc =3D -ENODEV; + goto done; + } + rc =3D copy_from_user(&roi, p, sizeof(roi)); + if (rc) { + rc =3D -EFAULT; + goto done; + } + + if (roi.is_read) { + memcpy(&roi.Roi, &data->roi_cfg, sizeof(roi.Roi)); + rc =3D copy_to_user(p, &roi, sizeof(roi)); + if (rc) { + vl53lx_errmsg("fail to copy Roi to user %d", rc); + rc =3D -EFAULT; + goto done; + } + } else { + if (data->enable_sensor) { + rc =3D -EBUSY; + vl53lx_errmsg("can't set roi while ranging\n"); + goto done; + } + memcpy(&data->roi_cfg, &roi.Roi, sizeof(data->roi_cfg)); + vl53lx_dbgmsg("ROI modified TopLeft(%d %d) BottomRight(%d %d)\n", data->= roi_cfg.TopLeftX, data->roi_cfg.TopLeftY, data->roi_cfg.BotRightX, data->ro= i_cfg.BotRightY); + } + +done: + mutex_unlock(&data->work_mutex); + return rc; +} + +static bool is_pid_in_list(pid_t pid, struct list_head *head) +{ + struct stmvl53lx_waiters *waiter; + + list_for_each_entry(waiter, head, list) + if (waiter->pid =3D=3D pid) + return true; + + return false; +} + +static bool is_new_data_for_me(struct stmvl53lx_data *data, pid_t pid, str= uct list_head *head) +{ + return data->is_data_valid && !is_pid_in_list(pid, head); +} + +static bool sleep_for_data_condition(struct stmvl53lx_data *data, pid_t pi= d, struct list_head *head) +{ + bool res; + + mutex_lock(&data->work_mutex); + res =3D is_new_data_for_me(data, pid, head); + mutex_unlock(&data->work_mutex); + + return res; +} + +static int sleep_for_data(struct stmvl53lx_data *data, pid_t pid, struct l= ist_head *head) +{ + int rc =3D 0; + + mutex_unlock(&data->work_mutex); + rc =3D wait_event_interruptible_timeout(data->waiter_for_data, sleep_for_= data_condition(data, pid, head), usecs_to_jiffies(2 * data->timing_budget)); + if (rc =3D=3D 0) + rc =3D -EAGAIN; + else + rc =3D 0; + mutex_lock(&data->work_mutex); + + return data->enable_sensor ? rc : -ENODEV; +} + +static int add_reader(pid_t pid, struct list_head *head) +{ + struct stmvl53lx_waiters *new_waiter; + + new_waiter =3D kmalloc(sizeof(struct stmvl53lx_waiters), GFP_KERNEL); + if (!new_waiter) + return -ENOMEM; + new_waiter->pid =3D pid; + list_add(&new_waiter->list, head); + + return 0; +} + +static int ctrl_mz_data_blocking_common(struct stmvl53lx_data *data, void = __user *p, bool is_additional) +{ + int rc =3D 0; + int rc0; + struct stmvl53lx_data_with_additional __user *d =3D p; + pid_t pid =3D current->pid; + + mutex_lock(&data->work_mutex); + if (data->is_device_remove) { + rc =3D -ENODEV; + goto done; + } + if (!data->enable_sensor) { + rc =3D -ENODEV; + goto done; + } + if (!is_new_data_for_me(data, pid, &data->mz_data_reader_list)) + rc =3D sleep_for_data(data, pid, &data->mz_data_reader_list); + if (rc) { + kill_mz_data(&data->meas.multi_range_data); + rc0 =3D copy_to_user(&d->data, &data->meas.multi_range_data, sizeof(VL53= LX_MultiRangingData_t)); + goto done; + } + + rc =3D copy_to_user(&d->data, &data->meas.multi_range_data, sizeof(VL53LX= _MultiRangingData_t)); + if (rc) + goto done; + if (is_additional) { + rc =3D copy_to_user(&d->additional_data, &data->meas.additional_data, si= zeof(VL53LX_AdditionalData_t)); + if (rc) + goto done; + } + rc =3D add_reader(pid, &data->mz_data_reader_list); + +done: + mutex_unlock(&data->work_mutex); + + return rc; +} + +static int ctrl_mz_data_common(struct stmvl53lx_data *data, void __user *p= , bool is_additional) +{ + struct stmvl53lx_data_with_additional __user *d =3D p; + int rc =3D 0; + + mutex_lock(&data->work_mutex); + if (data->is_device_remove) { + rc =3D -ENODEV; + goto done; + } + rc =3D copy_to_user(&d->data, &data->meas.multi_range_data, sizeof(VL53LX= _MultiRangingData_t)); + if (rc) { + vl53lx_dbgmsg("copy to user fail %d", rc); + rc =3D -EFAULT; + goto done; + } + if (is_additional) { + rc =3D copy_to_user(&d->additional_data, &data->meas.additional_data, si= zeof(VL53LX_AdditionalData_t)); + if (rc) { + vl53lx_dbgmsg("copy to user fail %d", rc); + rc =3D -EFAULT; + goto done; + } + } + if (!data->enable_sensor) + rc =3D -ENODEV; + +done: + mutex_unlock(&data->work_mutex); + return rc; +} + +static int ctrl_mz_data(struct stmvl53lx_data *data, void __user *p) +{ + return ctrl_mz_data_common(data, p, false); +} + +static int ctrl_mz_data_blocking(struct stmvl53lx_data *data, void __user = *p) +{ + return ctrl_mz_data_blocking_common(data, p, false); +} + +static int ctrl_calibration_data(struct stmvl53lx_data *data, void __user = *p) +{ + int rc =3D 0; + struct stmvl53lx_ioctl_calibration_data_t calib; + int data_offset =3D offsetof(struct stmvl53lx_ioctl_calibration_data_t, d= ata); + + mutex_lock(&data->work_mutex); + + if (data->is_device_remove) { + rc =3D -ENODEV; + goto done; + } + rc =3D copy_from_user(&calib, p, data_offset); + if (rc) { + vl53lx_errmsg("fail to detect read or write %d", rc); + rc =3D -EFAULT; + goto done; + } + + if (calib.is_read) { + memset(&calib.data, 0, sizeof(calib.data)); + rc =3D VL53LX_GetCalibrationData(&data->stdev, &calib.data); + if (rc) { + vl53lx_errmsg("VL53LX_GetCalibrationData fail %d", rc); + rc =3D store_last_error(data, rc); + goto done; + } + rc =3D copy_to_user(p + data_offset, &calib.data, + sizeof(calib.data)); + } else { + if (data->enable_sensor) { + rc =3D -EBUSY; + vl53lx_errmsg("can't set calib data while ranging\n"); + goto done; + } + rc =3D copy_from_user(&calib.data, p + data_offset, + sizeof(calib.data)); + if (rc) { + vl53lx_errmsg("fail to copy calib data"); + rc =3D -EFAULT; + goto done; + } + rc =3D VL53LX_SetCalibrationData(&data->stdev, &calib.data); + if (rc) { + vl53lx_errmsg("VL53LX_SetCalibrationData fail %d", rc); + rc =3D store_last_error(data, rc); + } + } + +done: + mutex_unlock(&data->work_mutex); + return rc; +} + +VL53LX_Error VL53LX_set_ref_spad_char_config( + VL53LX_DEV Dev, + uint8_t vcsel_period_a, + uint32_t phasecal_timeout_us, + uint16_t total_rate_target_mcps, + uint16_t max_count_rate_rtn_limit_mcps, + uint16_t min_count_rate_rtn_limit_mcps, + uint16_t fast_osc_frequency) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t buffer[2]; + + uint32_t macro_period_us =3D 0; + uint32_t timeout_mclks =3D 0; + + macro_period_us =3D VL53LX_calc_macro_period_us(fast_osc_frequency, vcsel= _period_a); + if (macro_period_us =3D=3D 0) + macro_period_us =3D 1; + + timeout_mclks =3D phasecal_timeout_us << 12; + timeout_mclks =3D timeout_mclks + (macro_period_us>>1); + timeout_mclks =3D timeout_mclks / macro_period_us; + + if (timeout_mclks > 0xFF) + pdev->gen_cfg.phasecal_config__timeout_macrop =3D 0xFF; + else + pdev->gen_cfg.phasecal_config__timeout_macrop =3D (uint8_t)timeout_mclks; + + pdev->tim_cfg.range_config__vcsel_period_a =3D vcsel_period_a; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_PHASECAL_CONFIG__TIMEOUT_MACROP, pd= ev->gen_cfg.phasecal_config__timeout_macrop); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrByte(Dev, VL53LX_RANGE_CONFIG__VCSEL_PERIOD_A, pdev-= >tim_cfg.range_config__vcsel_period_a); + + buffer[0] =3D pdev->tim_cfg.range_config__vcsel_period_a; + buffer[1] =3D pdev->tim_cfg.range_config__vcsel_period_a; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WriteMulti(Dev, VL53LX_SD_CONFIG__WOI_SD0, buffer, 2); + + pdev->customer.ref_spad_char__total_rate_target_mcps =3D total_rate_targe= t_mcps; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrWord(Dev, VL53LX_REF_SPAD_CHAR__TOTAL_RATE_TARGET_MC= PS, total_rate_target_mcps); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrWord(Dev, VL53LX_RANGE_CONFIG__SIGMA_THRESH, max_cou= nt_rate_rtn_limit_mcps); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WrWord(Dev, VL53LX_RANGE_CONFIG__MIN_COUNT_RATE_RTN_LI= MIT_MCPS, min_count_rate_rtn_limit_mcps); + + return status; +} + +VL53LX_Error VL53LX_start_test(VL53LX_DEV Dev, uint8_t test_mode__ctrl) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_WrByte(Dev, VL53LX_TEST_MODE__CTRL, test_mode__ctrl); + } + return status; +} + +VL53LX_Error VL53LX_poll_for_range_completion(VL53LX_DEV Dev, uint32_t tim= eout_ms) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t gpio__mux_active_high_hv =3D 0; + uint8_t interrupt_ready =3D 0; + + gpio__mux_active_high_hv =3D pdev->stat_cfg.gpio_hv_mux__ctrl & VL53LX_DE= VICEINTERRUPTLEVEL_ACTIVE_MASK; + + if (gpio__mux_active_high_hv =3D=3D VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_HI= GH) + interrupt_ready =3D 0x01; + else + interrupt_ready =3D 0x00; + + status =3D VL53LX_WaitValueMaskEx(Dev, timeout_ms, VL53LX_GPIO__TIO_HV_ST= ATUS, interrupt_ready, 0x01, VL53LX_POLLING_DELAY_MS); + return status; +} + +VL53LX_Error VL53LX_wait_for_test_completion(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + uint8_t data_ready =3D 0; + + if (pdev->wait_method =3D=3D VL53LX_WAIT_METHOD_BLOCKING) { + status =3D VL53LX_poll_for_range_completion(Dev, VL53LX_TEST_COMPLETION_= POLLING_TIMEOUT_MS); + + } else { + data_ready =3D 0; + while (data_ready =3D=3D 0x00 && status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_is_new_data_ready(Dev, &data_ready); + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_WaitMs(Dev, VL53LX_POLLING_DELAY_MS); + } + } + } + return status; +} + +VL53LX_Error VL53LX_clear_interrupt(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + pdev->sys_ctrl.system__interrupt_clear =3D VL53LX_CLEAR_RANGE_INT; + + status =3D VL53LX_WrByte(Dev, VL53LX_SYSTEM__INTERRUPT_CLEAR, pdev->sys_c= trl.system__interrupt_clear); + + return status; +} + +VL53LX_Error VL53LX_run_device_test(VL53LX_DEV Dev, VL53LX_DeviceTestMode = device_test_mode) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t comms_buffer[2]; + uint8_t gpio_hv_mux__ctrl =3D 0; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_RdByte(Dev, VL53LX_GPIO_HV_MUX__CTRL, &gpio_hv_mux__ct= rl); + + if (status =3D=3D VL53LX_ERROR_NONE) + pdev->stat_cfg.gpio_hv_mux__ctrl =3D gpio_hv_mux__ctrl; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_start_test(Dev, device_test_mode); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_wait_for_test_completion(Dev); + + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_ReadMulti(Dev, VL53LX_RESULT__RANGE_STATUS, comms_buff= er, 2); + + if (status =3D=3D VL53LX_ERROR_NONE) { + pdev->sys_results.result__range_status =3D comms_buffer[0]; + pdev->sys_results.result__report_status =3D comms_buffer[1]; + } + + pdev->sys_results.result__range_status &=3D VL53LX_RANGE_STATUS__RANGE_ST= ATUS_MASK; + + if (status =3D=3D VL53LX_ERROR_NONE) { + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_clear_interrupt(Dev); + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_start_test(Dev, 0x00); + + return status; +} + +VL53LX_Error VL53LX_run_ref_spad_char(VL53LX_DEV Dev, VL53LX_Error *pcal_s= tatus) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + uint8_t comms_buffer[6]; + + VL53LX_refspadchar_config_t *prefspadchar =3D &(pdev->refspadchar); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_enable_powerforce(Dev); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D + VL53LX_set_ref_spad_char_config( + Dev, + prefspadchar->VL53LX_p_005, + prefspadchar->timeout_us, + prefspadchar->target_count_rate_mcps, + prefspadchar->max_count_rate_limit_mcps, + prefspadchar->min_count_rate_limit_mcps, + pdev->stat_nvm.osc_measured__fast_osc__frequency); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_run_device_test(Dev, prefspadchar->device_test_mode); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_ReadMulti(Dev, VL53LX_REF_SPAD_CHAR_RESULT__NUM_ACTUAL= _REF_SPADS, comms_buffer, 2); + + if (status =3D=3D VL53LX_ERROR_NONE) { + pdev->dbg_results.ref_spad_char_result__num_actual_ref_spads =3D comms_b= uffer[0]; + pdev->dbg_results.ref_spad_char_result__ref_location =3D comms_buffer[1]; + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WriteMulti(Dev, VL53LX_REF_SPAD_MAN__NUM_REQUESTED_REF= _SPADS, comms_buffer, 2); + + if (status =3D=3D VL53LX_ERROR_NONE) { + pdev->customer.ref_spad_man__num_requested_ref_spads =3D comms_buffer[0]; + pdev->customer.ref_spad_man__ref_location =3D comms_buffer[1]; + } + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_ReadMulti(Dev, VL53LX_RESULT__SPARE_0_SD1, comms_buffe= r, 6); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_WriteMulti(Dev, VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF= _0, comms_buffer, 6); + + if (status =3D=3D VL53LX_ERROR_NONE) { + pdev->customer.global_config__spad_enables_ref_0 =3D comms_buffer[0]; + pdev->customer.global_config__spad_enables_ref_1 =3D comms_buffer[1]; + pdev->customer.global_config__spad_enables_ref_2 =3D comms_buffer[2]; + pdev->customer.global_config__spad_enables_ref_3 =3D comms_buffer[3]; + pdev->customer.global_config__spad_enables_ref_4 =3D comms_buffer[4]; + pdev->customer.global_config__spad_enables_ref_5 =3D comms_buffer[5]; + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + switch (pdev->sys_results.result__range_status) { + case VL53LX_DEVICEERROR_REFSPADCHARNOTENOUGHDPADS: + status =3D VL53LX_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS; + break; + case VL53LX_DEVICEERROR_REFSPADCHARMORETHANTARGET: + status =3D VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH; + break; + case VL53LX_DEVICEERROR_REFSPADCHARLESSTHANTARGET: + status =3D VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW; + break; + } + } + *pcal_status =3D status; + IGNORE_STATUS(IGNORE_REF_SPAD_CHAR_NOT_ENOUGH_SPADS, VL53LX_WARNING_REF_S= PAD_CHAR_NOT_ENOUGH_SPADS, status); + IGNORE_STATUS(IGNORE_REF_SPAD_CHAR_RATE_TOO_HIGH, VL53LX_WARNING_REF_SPAD= _CHAR_RATE_TOO_HIGH, status); + IGNORE_STATUS(IGNORE_REF_SPAD_CHAR_RATE_TOO_LOW, VL53LX_WARNING_REF_SPAD_= CHAR_RATE_TOO_LOW, status); + + return status; +} + +VL53LX_Error VL53LX_PerformRefSpadManagement(VL53LX_DEV Dev) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_Error RawStatus; + uint8_t dcrbuffer[24]; + uint8_t *commbuf; + uint8_t numloc[2] =3D {5, 3}; + VL53LX_LLDriverData_t *pdev; + VL53LX_customer_nvm_managed_t *pc; + VL53LX_DistanceModes DistanceMode; + + pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + pc =3D &pdev->customer; + + if (Status =3D=3D VL53LX_ERROR_NONE) { + DistanceMode =3D VL53LXDevDataGet(Dev, CurrentParameters.DistanceMode); + Status =3D VL53LX_run_ref_spad_char(Dev, &RawStatus); + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_SetDistanceMode(Dev, DistanceMode); + } + + if (Status =3D=3D VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH) { + Status =3D VL53LX_read_nvm_raw_data(Dev, (uint8_t)(0xA0 >> 2), (uint8_t)= (24 >> 2), dcrbuffer); + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_WriteMulti(Dev, VL53LX_REF_SPAD_MAN__NUM_REQUESTED_RE= F_SPADS, numloc, 2); + + if (Status =3D=3D VL53LX_ERROR_NONE) { + pc->ref_spad_man__num_requested_ref_spads =3D numloc[0]; + pc->ref_spad_man__ref_location =3D numloc[1]; + } + commbuf =3D &dcrbuffer[16]; + + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_WriteMulti(Dev, VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_RE= F_0, commbuf, 6); + + if (Status =3D=3D VL53LX_ERROR_NONE) { + pc->global_config__spad_enables_ref_0 =3D commbuf[0]; + pc->global_config__spad_enables_ref_1 =3D commbuf[1]; + pc->global_config__spad_enables_ref_2 =3D commbuf[2]; + pc->global_config__spad_enables_ref_3 =3D commbuf[3]; + pc->global_config__spad_enables_ref_4 =3D commbuf[4]; + pc->global_config__spad_enables_ref_5 =3D commbuf[5]; + } + } + return Status; +} + +static int ctrl_perform_calibration_ref_spad_lock(struct stmvl53lx_data *d= ata, struct stmvl53lx_ioctl_perform_calibration_t *calib) +{ + int rc =3D VL53LX_PerformRefSpadManagement(&data->stdev); + + if (rc) { + vl53lx_errmsg("VL53LX_PerformRefSpadManagement fail =3D> %d", rc); + rc =3D store_last_error(data, rc); + } + return rc; +} + +void VL53LX_hist_xtalk_extract_data_init(VL53LX_hist_xtalk_extract_data_t = *pxtalk_data) +{ int32_t lb =3D 0; + + pxtalk_data->sample_count =3D 0U; + pxtalk_data->pll_period_mm =3D 0U; + pxtalk_data->peak_duration_us_sum =3D 0U; + pxtalk_data->effective_spad_count_sum =3D 0U; + pxtalk_data->zero_distance_phase_sum =3D 0U; + pxtalk_data->zero_distance_phase_avg =3D 0U; + pxtalk_data->event_scaler_sum =3D 0U; + pxtalk_data->event_scaler_avg =3D 4096U; + pxtalk_data->signal_events_sum =3D 0; + pxtalk_data->xtalk_rate_kcps_per_spad =3D 0U; + pxtalk_data->VL53LX_p_012 =3D 0U; + pxtalk_data->VL53LX_p_013 =3D 0U; + pxtalk_data->target_start =3D 0U; + + for (lb =3D 0; lb < VL53LX_XTALK_HISTO_BINS; lb++) + pxtalk_data->bin_data_sums[lb] =3D 0; +} + +VL53LX_Error VL53LX_wait_for_range_completion(VL53LX_DEV Dev) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + uint8_t data_ready =3D 0; + + if (pdev->wait_method =3D=3D VL53LX_WAIT_METHOD_BLOCKING) { + status =3D VL53LX_poll_for_range_completion(Dev, VL53LX_RANGE_COMPLETION= _POLLING_TIMEOUT_MS); + } else { + data_ready =3D 0; + while (data_ready =3D=3D 0x00 && status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_is_new_data_ready(Dev, &data_ready); + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_WaitMs(Dev, VL53LX_POLLING_DELAY_MS); + } + } + } + return status; +} + +VL53LX_Error VL53LX_hist_xtalk_extract_calc_window( + int16_t target_distance_mm, + uint16_t target_width_oversize, + VL53LX_histogram_bin_data_t *phist_bins, + VL53LX_hist_xtalk_extract_data_t *pxtalk_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + pxtalk_data->pll_period_mm =3D VL53LX_calc_pll_period_mm(phist_bins->VL53= LX_p_015); + if (pxtalk_data->pll_period_mm =3D=3D 0) + pxtalk_data->pll_period_mm =3D 1; + + pxtalk_data->xtalk_width_phase =3D (int32_t)phist_bins->vcsel_width * 128; + pxtalk_data->target_width_phase =3D pxtalk_data->xtalk_width_phase + (int= 32_t)target_width_oversize * 128; + + pxtalk_data->xtalk_start_phase =3D (int32_t)phist_bins->zero_distance_pha= se - (pxtalk_data->xtalk_width_phase / 2); + pxtalk_data->xtalk_end_phase =3D (int32_t)pxtalk_data->xtalk_start_phase= + pxtalk_data->xtalk_width_phase; + + if (pxtalk_data->xtalk_start_phase < 0) + pxtalk_data->xtalk_start_phase =3D 0; + + pxtalk_data->VL53LX_p_012 =3D (uint8_t)(pxtalk_data->xtalk_start_phase / = 2048); + pxtalk_data->VL53LX_p_013 =3D (uint8_t)((pxtalk_data->xtalk_end_phase + 2= 047) / 2048); + + pxtalk_data->target_start_phase =3D (int32_t)target_distance_mm * 2048 *= 16; + pxtalk_data->target_start_phase +=3D ((int32_t)pxtalk_data->pll_period_mm= / 2); + pxtalk_data->target_start_phase /=3D (int32_t)pxtalk_data->pll_period_mm; + pxtalk_data->target_start_phase +=3D (int32_t)phist_bins->zero_distance_p= hase; + pxtalk_data->target_start_phase -=3D (pxtalk_data->target_width_phase / 2= ); + pxtalk_data->target_end_phase =3D (int32_t)pxtalk_data->target_start_pha= se + pxtalk_data->target_width_phase; + + if (pxtalk_data->target_start_phase < 0) + pxtalk_data->target_start_phase =3D 0; + + pxtalk_data->target_start =3D (uint8_t)(pxtalk_data->target_start_phase /= 2048); + + if (pxtalk_data->VL53LX_p_013 > (pxtalk_data->target_start-1)) + pxtalk_data->VL53LX_p_013 =3D pxtalk_data->target_start-1; + + pxtalk_data->effective_width =3D (2048 * ((int32_t)pxtalk_data->VL53LX_p_= 013+1)); + pxtalk_data->effective_width -=3D pxtalk_data->xtalk_start_phase; + + if (pxtalk_data->effective_width > pxtalk_data->xtalk_width_phase) + pxtalk_data->effective_width =3D pxtalk_data->xtalk_width_phase; + + if (pxtalk_data->effective_width < 1) + pxtalk_data->effective_width =3D 1; + + pxtalk_data->event_scaler =3D pxtalk_data->xtalk_width_phase * 1000; + pxtalk_data->event_scaler +=3D (pxtalk_data->effective_width / 2); + pxtalk_data->event_scaler /=3D pxtalk_data->effective_width; + + if (pxtalk_data->event_scaler < 1000) + pxtalk_data->event_scaler =3D 1000; + + if (pxtalk_data->event_scaler > 4000) + pxtalk_data->event_scaler =3D 4000; + + pxtalk_data->event_scaler_sum +=3D pxtalk_data->event_scaler; + + pxtalk_data->peak_duration_us_sum +=3D (uint32_t)phist_bins->peak_duratio= n_us; + + pxtalk_data->effective_spad_count_sum +=3D (uint32_t)phist_bins->result__= dss_actual_effective_spads; + + pxtalk_data->zero_distance_phase_sum +=3D (uint32_t)phist_bins->zero_dist= ance_phase; + + return status; +} + +VL53LX_Error VL53LX_hist_xtalk_extract_calc_event_sums(VL53LX_histogram_bi= n_data_t *phist_bins, VL53LX_hist_xtalk_extract_data_t *pxtalk_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + uint8_t lb =3D 0; + uint8_t i =3D 0; + + for (lb =3D pxtalk_data->VL53LX_p_012; lb <=3D pxtalk_data->VL53LX_p_013= ; lb++) { + i =3D (lb + phist_bins->number_of_ambient_bins + phist_bins->VL53LX_p_02= 1) % phist_bins->VL53LX_p_021; + + pxtalk_data->signal_events_sum +=3D phist_bins->bin_data[i]; + pxtalk_data->signal_events_sum -=3D phist_bins->VL53LX_p_028; + } + + for (lb =3D 0; lb < VL53LX_XTALK_HISTO_BINS && lb < phist_bins->VL53LX_= p_021; lb++) { + i =3D (lb + phist_bins->number_of_ambient_bins + phist_bins->VL53LX_p_02= 1) % phist_bins->VL53LX_p_021; + + pxtalk_data->bin_data_sums[lb] +=3D phist_bins->bin_data[i]; + pxtalk_data->bin_data_sums[lb] -=3D phist_bins->VL53LX_p_028; + } + + pxtalk_data->sample_count +=3D 1; + return status; +} + +VL53LX_Error VL53LX_hist_xtalk_extract_update( + int16_t target_distance_mm, + uint16_t target_width_oversize, + VL53LX_histogram_bin_data_t *phist_bins, + VL53LX_hist_xtalk_extract_data_t *pxtalk_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + status =3D VL53LX_hist_xtalk_extract_calc_window(target_distance_mm, targ= et_width_oversize, phist_bins, pxtalk_data); + + if (status =3D=3D VL53LX_ERROR_NONE) { + status =3D VL53LX_hist_xtalk_extract_calc_event_sums(phist_bins, pxtalk_= data); + } + return status; +} + +VL53LX_Error VL53LX_hist_xtalk_extract_calc_rate_per_spad(VL53LX_hist_xtal= k_extract_data_t *pxtalk_data) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + uint64_t tmp64_0 =3D 0; + uint64_t tmp64_1 =3D 0; + uint64_t xtalk_per_spad =3D 0; + + tmp64_1 =3D (uint64_t)pxtalk_data->effective_spad_count_sum * (uint64_t)p= xtalk_data->peak_duration_us_sum; + + if (pxtalk_data->signal_events_sum < 0) { + pxtalk_data->signal_events_sum =3D 0; + + tmp64_0 =3D ((uint64_t)pxtalk_data->sample_count * (uint64_t)pxtalk_data= ->event_scaler_avg * 256U) << 9U; + if (tmp64_0 > 0) { + pxtalk_data->signal_events_sum =3D (int32_t)do_division_u((50U * tmp64_= 1), tmp64_0); + } + } + tmp64_0 =3D ((uint64_t)pxtalk_data->signal_events_sum * (uint64_t)pxtalk_= data->sample_count * (uint64_t)pxtalk_data->event_scaler_avg * 256U) << 9U; + if (tmp64_1 > 0U) { + tmp64_0 =3D tmp64_0 + (tmp64_1 >> 1U); + xtalk_per_spad =3D do_division_u(tmp64_0, tmp64_1); + } else { + xtalk_per_spad =3D (uint64_t)tmp64_0; + } + + pxtalk_data->xtalk_rate_kcps_per_spad =3D (uint32_t)xtalk_per_spad; + return status; +} + +VL53LX_Error VL53LX_hist_xtalk_extract_calc_shape(VL53LX_hist_xtalk_extrac= t_data_t *pxtalk_data, VL53LX_xtalk_histogram_shape_t *pxtalk_shape) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + + int32_t lb =3D 0; + uint64_t total_events =3D 0U; + uint64_t tmp64_0 =3D 0U; + int32_t remaining_area =3D 1024; + + pxtalk_shape->VL53LX_p_019 =3D 0; + pxtalk_shape->VL53LX_p_020 =3D VL53LX_XTALK_HISTO_BINS; + pxtalk_shape->VL53LX_p_021 =3D VL53LX_XTALK_HISTO_BINS; + + pxtalk_shape->zero_distance_phase =3D (uint16_t)pxtalk_data->zero_distanc= e_phase_avg; + pxtalk_shape->phasecal_result__reference_phase =3D (uint16_t)pxtalk_data-= >zero_distance_phase_avg + (3*2048); + + if (pxtalk_data->signal_events_sum > 0) + total_events =3D (uint64_t)pxtalk_data->signal_events_sum * (uint64_t)px= talk_data->event_scaler_avg; + else + total_events =3D 1; + if (total_events =3D=3D 0) + total_events =3D 1; + + remaining_area =3D 1024; + pxtalk_data->max_shape_value =3D 0; + + for (lb =3D 0; lb < VL53LX_XTALK_HISTO_BINS; lb++) { + if ((lb < (int32_t)pxtalk_data->VL53LX_p_012 || lb > (int32_t)pxtalk_dat= a->VL53LX_p_013) || pxtalk_data->bin_data_sums[lb] < 0) { + if (remaining_area > 0 && remaining_area < 1024) { + if (remaining_area > pxtalk_data->max_shape_value) { + pxtalk_shape->bin_data[lb] =3D (uint32_t)pxtalk_data->max_shape_value; + remaining_area -=3D pxtalk_data->max_shape_value; + } else { + pxtalk_shape->bin_data[lb] =3D (uint32_t)remaining_area; + remaining_area =3D 0; + } + } else { + pxtalk_shape->bin_data[lb] =3D 0; + } + } else { + tmp64_0 =3D (uint64_t)pxtalk_data->bin_data_sums[lb] * 1024U * 1000U; + tmp64_0 +=3D (total_events >> 1); + tmp64_0 =3D do_division_u(tmp64_0, total_events); + if (tmp64_0 > 0xFFFFU) + tmp64_0 =3D 0xFFFFU; + + pxtalk_shape->bin_data[lb] =3D (uint32_t)tmp64_0; + + if ((int32_t)pxtalk_shape->bin_data[lb] > pxtalk_data->max_shape_value) + pxtalk_data->max_shape_value =3D (int32_t)pxtalk_shape->bin_data[lb]; + + remaining_area -=3D (int32_t)pxtalk_shape->bin_data[lb]; + } + } + return status; +} + +VL53LX_Error VL53LX_hist_xtalk_extract_fini( + VL53LX_histogram_bin_data_t *phist_bins, + VL53LX_hist_xtalk_extract_data_t *pxtalk_data, + VL53LX_xtalk_calibration_results_t *pxtalk_cal, + VL53LX_xtalk_histogram_shape_t *pxtalk_shape) +{ + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_xtalk_calibration_results_t *pX =3D pxtalk_cal; + + if (pxtalk_data->sample_count > 0) { + pxtalk_data->event_scaler_avg =3D pxtalk_data->event_scaler_sum; + pxtalk_data->event_scaler_avg +=3D (pxtalk_data->sample_count >> 1); + pxtalk_data->event_scaler_avg /=3D pxtalk_data->sample_count; + + status =3D VL53LX_hist_xtalk_extract_calc_rate_per_spad(pxtalk_data); + if (status =3D=3D VL53LX_ERROR_NONE) { + pxtalk_data->zero_distance_phase_avg =3D pxtalk_data->zero_distance_ph= ase_sum; + pxtalk_data->zero_distance_phase_avg +=3D (pxtalk_data->sample_count >>= 1); + pxtalk_data->zero_distance_phase_avg /=3D pxtalk_data->sample_count; + status =3D VL53LX_hist_xtalk_extract_calc_shape(pxtalk_data, pxtalk_sha= pe); + + pxtalk_shape->phasecal_result__vcsel_start =3D phist_bins->phasecal_res= ult__vcsel_start; + pxtalk_shape->cal_config__vcsel_start =3D phist_bins->cal_config__vcsel= _start; + pxtalk_shape->vcsel_width =3D phist_bins->vcsel_width; + pxtalk_shape->VL53LX_p_015 =3D phist_bins->VL53LX_p_015; + } + + if (status =3D=3D VL53LX_ERROR_NONE) { + pX->algo__crosstalk_compensation_plane_offset_kcps =3D pxtalk_data->xta= lk_rate_kcps_per_spad; + pX->algo__crosstalk_compensation_x_plane_gradient_kcps =3D 0U; + pX->algo__crosstalk_compensation_y_plane_gradient_kcps =3D 0U; + } + } + return status; +} + +VL53LX_Error VL53LX_run_hist_xtalk_extraction(VL53LX_DEV Dev, int16_t cal_= distance_mm, VL53LX_Error *pcal_status) +{ + #define OVERSIZE 4 + VL53LX_Error status =3D VL53LX_ERROR_NONE; + VL53LX_LLDriverData_t *pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + VL53LX_xtalkextract_config_t *pX =3D &(pdev->xtalk_extract_cfg); + VL53LX_xtalk_config_t *pC =3D &(pdev->xtalk_cfg); + VL53LX_xtalk_calibration_results_t *pXC =3D &(pdev->xtalk_cal); + + uint8_t smudge_corr_en =3D 0; + uint8_t i =3D 0; + int8_t k =3D 0; + uint8_t nbloops; + int32_t initMergeSize =3D 0; + int32_t MergeEnabled =3D 0; + uint32_t deltaXtalk; + uint32_t stepXtalk; + uint32_t XtalkMin; + uint32_t XtalkMax; + uint8_t measurement_mode =3D VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK; + int8_t MaxId; + uint8_t histo_merge_nb; + uint8_t wait_for_accumulation; + VL53LX_range_results_t *prange_results =3D (VL53LX_range_results_t *) pde= v->wArea1; + uint8_t Very1stRange =3D 0; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D + VL53LX_set_preset_mode( + Dev, + VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE, + pX->dss_config__target_total_rate_mcps, + pX->phasecal_config_timeout_us, + pX->mm_config_timeout_us, + pX->range_config_timeout_us, + 100); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_disable_xtalk_compensation(Dev); + + smudge_corr_en =3D pdev->smudge_correct_config.smudge_corr_enabled; + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_dynamic_xtalk_correction_disable(Dev); + + VL53LX_load_patch(Dev); + + VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, &initM= ergeSize); + VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE, &MergeEnabled); + memset(&pdev->xtalk_cal, 0, sizeof(pdev->xtalk_cal)); + + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_init_and_start_range(Dev, measurement_mode, VL53LX_DEV= ICECONFIGLEVEL_CUSTOMER_ONWARDS); + + MaxId =3D pdev->tuning_parms.tp_hist_merge_max_size - 1; + nbloops =3D (MergeEnabled =3D=3D 0 ? 1 : 2); + for (k =3D 0; k < nbloops; k++) { + VL53LX_hist_xtalk_extract_data_init(&(pdev->xtalk_extract)); + VL53LX_set_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, k * M= axId + 1); + + for (i =3D 0; i <=3D pX->num_of_samples; i++) { + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_wait_for_range_completion(Dev); + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_get_device_results(Dev, VL53LX_DEVICERESULTSLEVEL_FU= LL, prange_results); + Very1stRange =3D (pdev->ll_state.rd_device_state =3D=3D VL53LX_DEVICEST= ATE_RANGING_WAIT_GPH_SYNC); + + VL53LX_compute_histo_merge_nb(Dev, &histo_merge_nb); + wait_for_accumulation =3D ((k !=3D 0) && (MergeEnabled) && (status =3D= =3D VL53LX_ERROR_NONE) && (histo_merge_nb < pdev->tuning_parms.tp_hist_merg= e_max_size)); + if (wait_for_accumulation) + i =3D 0; + else { + if ((status =3D=3D VL53LX_ERROR_NONE) && (!Very1stRange)) { + status =3D VL53LX_hist_xtalk_extract_update(cal_distance_mm, OVERSIZE= , &(pdev->hist_data), &(pdev->xtalk_extract)); + } + } + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_clear_interrupt_and_enable_next_range(Dev, measureme= nt_mode); + } + if (status =3D=3D VL53LX_ERROR_NONE) + status =3D VL53LX_hist_xtalk_extract_fini(&(pdev->hist_data), &(pdev->x= talk_extract), &(pdev->xtalk_cal), &(pdev->xtalk_shapes.xtalk_shape)); + + if (status =3D=3D VL53LX_ERROR_NONE) { + pXC->algo__xtalk_cpo_HistoMerge_kcps[k * MaxId] =3D pXC->algo__crosstal= k_compensation_plane_offset_kcps; + } + } + VL53LX_stop_range(Dev); + + VL53LX_set_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, initMe= rgeSize); + VL53LX_unload_patch(Dev); + + if (status !=3D VL53LX_ERROR_NONE) + status =3D VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL; + else if ((MergeEnabled =3D=3D 1) && (MaxId > 0)) { + XtalkMin =3D pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0]; + XtalkMax =3D pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[MaxId]; + pdev->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps =3D Xtalk= Min; + if (XtalkMax > XtalkMin) { + deltaXtalk =3D XtalkMax - XtalkMin; + stepXtalk =3D deltaXtalk / MaxId; + for (k =3D 1; k < MaxId; k++) + pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[k] =3D XtalkMin + stepX= talk * k; + } else + status =3D VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL; + } + if (status =3D=3D VL53LX_ERROR_NONE) { + pC->algo__crosstalk_compensation_x_plane_gradient_kcps =3D pXC->algo__cr= osstalk_compensation_x_plane_gradient_kcps; + pC->algo__crosstalk_compensation_y_plane_gradient_kcps =3D pXC->algo__cr= osstalk_compensation_y_plane_gradient_kcps; + pC->algo__crosstalk_compensation_plane_offset_kcps =3D pXC->algo__crosst= alk_compensation_plane_offset_kcps; + } + pdev->xtalk_results.cal_status =3D status; + *pcal_status =3D pdev->xtalk_results.cal_status; + + status =3D VL53LX_enable_xtalk_compensation(Dev); + if (smudge_corr_en =3D=3D 1) + status =3D VL53LX_dynamic_xtalk_correction_enable(Dev); + + return status; +} + +VL53LX_Error VL53LX_PerformXTalkCalibration(VL53LX_DEV Dev) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + VL53LX_Error UStatus; + int16_t CalDistanceMm; + VL53LX_xtalk_calibration_results_t xtalk; + + VL53LX_CalibrationData_t caldata; + VL53LX_LLDriverData_t *pLLData; + int i; + uint32_t *pPlaneOffsetKcps; + uint32_t Margin =3D BDTable[VL53LX_TUNING_XTALK_FULL_ROI_BIN_SUM_MARGIN]; + uint32_t DefaultOffset =3D BDTable[VL53LX_TUNING_XTALK_FULL_ROI_DEFAULT_O= FFSET]; + uint32_t *pLLDataPlaneOffsetKcps; + uint32_t sum =3D 0; + uint8_t binok =3D 0; + + pPlaneOffsetKcps =3D &caldata.customer.algo__crosstalk_compensation_plane= _offset_kcps; + pLLData =3D VL53LXDevStructGetLLDriverHandle(Dev); + pLLDataPlaneOffsetKcps =3D &pLLData->xtalk_cal.algo__crosstalk_compensati= on_plane_offset_kcps; + + CalDistanceMm =3D (int16_t) + BDTable[VL53LX_TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM]; + Status =3D VL53LX_run_hist_xtalk_extraction(Dev, CalDistanceMm, &UStatus); + + VL53LX_GetCalibrationData(Dev, &caldata); + for (i =3D 0; i < VL53LX_XTALK_HISTO_BINS; i++) { + sum +=3D caldata.xtalkhisto.xtalk_shape.bin_data[i]; + if (caldata.xtalkhisto.xtalk_shape.bin_data[i] > 0) + binok++; + } + if ((UStatus =3D=3D VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL) || (s= um > (1024 + Margin)) || (sum < (1024 - Margin)) || (binok < 3)) { + *pPlaneOffsetKcps =3D DefaultOffset; + *pLLDataPlaneOffsetKcps =3D DefaultOffset; + caldata.xtalkhisto.xtalk_shape.bin_data[0] =3D 307; + caldata.xtalkhisto.xtalk_shape.bin_data[1] =3D 410; + caldata.xtalkhisto.xtalk_shape.bin_data[2] =3D 410; + caldata.xtalkhisto.xtalk_shape.bin_data[3] =3D 307; + for (i =3D 4; i < VL53LX_XTALK_HISTO_BINS; i++) + caldata.xtalkhisto.xtalk_shape.bin_data[i] =3D 0; + for (i =3D 0; i < VL53LX_BIN_REC_SIZE; i++) + caldata.algo__xtalk_cpo_HistoMerge_kcps[i] =3D DefaultOffset + DefaultO= ffset * i; + VL53LX_SetCalibrationData(Dev, &caldata); + } + + if (Status =3D=3D VL53LX_ERROR_NONE) { + Status =3D VL53LX_get_current_xtalk_settings(Dev, &xtalk); + Status =3D VL53LX_set_tuning_parm(Dev, VL53LX_TUNINGPARM_DYNXTALK_NODETE= CT_XTALK_OFFSET_KCPS, xtalk.algo__crosstalk_compensation_plane_offset_kcps); + } + + return Status; +} + +static int ctrl_perform_calibration_crosstalk_lock(struct stmvl53lx_data *= data, struct stmvl53lx_ioctl_perform_calibration_t *calib) +{ + int rc =3D 0; + + rc =3D stmvl53lx_sendparams(data); + if (rc) + goto done; + + rc =3D VL53LX_PerformXTalkCalibration(&data->stdev); + if (rc) { + vl53lx_errmsg("VL53LX_PerformXTalkCalibration fail =3D> %d", rc); + rc =3D store_last_error(data, rc); + } + + data->crosstalk_enable =3D 1; +done: + return rc; +} + +VL53LX_Error VL53LX_PerformOffsetSimpleCalibration(VL53LX_DEV Dev, int32_t= CalDistanceMilliMeter) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + int32_t sum_ranging; + uint8_t offset_meas; + int16_t Max, UnderMax, OverMax, Repeat; + int32_t total_count, inloopcount; + int32_t IncRounding; + int16_t meanDistance_mm; + int16_t offset; + VL53LX_MultiRangingData_t RangingMeasurementData; + VL53LX_LLDriverData_t *pdev; + uint8_t goodmeas; + VL53LX_Error SmudgeStatus =3D VL53LX_ERROR_NONE; + uint8_t smudge_corr_en; + VL53LX_TargetRangeData_t *pRange; + + pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + smudge_corr_en =3D pdev->smudge_correct_config.smudge_corr_enabled; + SmudgeStatus =3D VL53LX_dynamic_xtalk_correction_disable(Dev); + + pdev->customer.algo__part_to_part_range_offset_mm =3D 0; + pdev->customer.mm_config__inner_offset_mm =3D 0; + pdev->customer.mm_config__outer_offset_mm =3D 0; + memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data)); + Repeat =3D BDTable[VL53LX_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT]; + Max =3D BDTable[VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER= ]; + UnderMax =3D 1 + (Max / 2); + OverMax =3D Max + (Max / 2); + sum_ranging =3D 0; + total_count =3D 0; + + while ((Repeat > 0) && (Status =3D=3D VL53LX_ERROR_NONE)) { + Status =3D VL53LX_StartMeasurement(Dev); + if (Status =3D=3D VL53LX_ERROR_NONE) { + VL53LX_WaitMeasurementDataReady(Dev); + VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData); + VL53LX_ClearInterruptAndStartMeasurement(Dev); + } + inloopcount =3D 0; + offset_meas =3D 0; + while ((Status =3D=3D VL53LX_ERROR_NONE) && (inloopcount < Max) && (offs= et_meas < OverMax)) { + Status =3D VL53LX_WaitMeasurementDataReady(Dev); + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData); + pRange =3D &(RangingMeasurementData.RangeData[0]); + goodmeas =3D (pRange->RangeStatus =3D=3D VL53LX_RANGESTATUS_RANGE_VALID= ); + if ((Status =3D=3D VL53LX_ERROR_NONE) && goodmeas) { + sum_ranging +=3D pRange->RangeMilliMeter; + inloopcount++; + } + Status =3D VL53LX_ClearInterruptAndStartMeasurement(Dev); + offset_meas++; + } + total_count +=3D inloopcount; + if (inloopcount < UnderMax) + Status =3D VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL; + + VL53LX_StopMeasurement(Dev); + Repeat--; + } + if ((SmudgeStatus =3D=3D VL53LX_ERROR_NONE) && (smudge_corr_en =3D=3D 1)) + SmudgeStatus =3D VL53LX_dynamic_xtalk_correction_enable(Dev); + + if ((sum_ranging < 0) || (sum_ranging > ((int32_t) total_count * 0xffff))) + Status =3D VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH; + + if ((Status =3D=3D VL53LX_ERROR_NONE) && (total_count > 0)) { + IncRounding =3D total_count / 2; + meanDistance_mm =3D (int16_t)((sum_ranging + IncRounding) / total_count); + offset =3D (int16_t)CalDistanceMilliMeter - meanDistance_mm; + pdev->customer.algo__part_to_part_range_offset_mm =3D 0; + pdev->customer.mm_config__inner_offset_mm =3D offset; + pdev->customer.mm_config__outer_offset_mm =3D offset; + + Status =3D VL53LX_set_customer_nvm_managed(Dev, &(pdev->customer)); + } + return Status; +} + +static int ctrl_perform_simple_calibration_offset_lock(struct stmvl53lx_da= ta *data, struct stmvl53lx_ioctl_perform_calibration_t *calib) +{ + int rc =3D 0; + + data->is_delay_allowed =3D 1; + rc =3D stmvl53lx_sendparams(data); + if (rc) + goto done; + + rc =3D VL53LX_PerformOffsetSimpleCalibration(&data->stdev, calib->param1); + data->is_delay_allowed =3D 0; + if (rc) { + vl53lx_errmsg( + "VL53LX_PerformOffsetSimpleCalibration fail =3D> %d", rc); + rc =3D store_last_error(data, rc); + } + +done: + return rc; +} + +VL53LX_Error VL53LX_GetDistanceMode(VL53LX_DEV Dev, VL53LX_DistanceModes *= pDistanceMode) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + + *pDistanceMode =3D VL53LXDevDataGet(Dev, CurrentParameters.DistanceMode); + + return Status; +} + +VL53LX_Error VL53LX_PerformOffsetPerVcselCalibration(VL53LX_DEV Dev, int32= _t CalDistanceMilliMeter) +{ + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + int32_t sum_ranging_range_A, sum_ranging_range_B; + uint8_t offset_meas_range_A, offset_meas_range_B; + int16_t Max, UnderMax, OverMax, Repeat; + int32_t inloopcount; + int32_t IncRounding; + int16_t meanDistance_mm; + VL53LX_MultiRangingData_t RangingMeasurementData; + VL53LX_LLDriverData_t *pdev; + uint8_t goodmeas; + VL53LX_DistanceModes currentDist; + VL53LX_DistanceModes DistMode[3] =3D {VL53LX_DISTANCEMODE_SHORT, VL53LX_D= ISTANCEMODE_MEDIUM, VL53LX_DISTANCEMODE_LONG}; + int16_t offsetA[3] =3D {0, 0, 0}; + int16_t offsetB[3] =3D {0, 0, 0}; + + VL53LX_Error SmudgeStatus =3D VL53LX_ERROR_NONE; + uint8_t smudge_corr_en, ics; + VL53LX_TargetRangeData_t *pRange; + + pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + + smudge_corr_en =3D pdev->smudge_correct_config.smudge_corr_enabled; + SmudgeStatus =3D VL53LX_dynamic_xtalk_correction_disable(Dev); + + pdev->customer.algo__part_to_part_range_offset_mm =3D 0; + pdev->customer.mm_config__inner_offset_mm =3D 0; + pdev->customer.mm_config__outer_offset_mm =3D 0; + pdev->customer.mm_config__outer_offset_mm =3D 0; + memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data)); + + Repeat =3D 0; + if (IsL4(Dev)) + Repeat =3D 1; + Max =3D 2 * BDTable[VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NU= MBER]; + UnderMax =3D 1 + (Max / 2); + OverMax =3D Max + (Max / 2); + + Status =3D VL53LX_GetDistanceMode(Dev, ¤tDist); + + while ((Repeat < 3) && (Status =3D=3D VL53LX_ERROR_NONE)) { + Status =3D VL53LX_SetDistanceMode(Dev, DistMode[Repeat]); + Status =3D VL53LX_StartMeasurement(Dev); + + if (Status =3D=3D VL53LX_ERROR_NONE) { + VL53LX_WaitMeasurementDataReady(Dev); + VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData); + VL53LX_ClearInterruptAndStartMeasurement(Dev); + } + inloopcount =3D 0; + offset_meas_range_A =3D 0; + sum_ranging_range_A =3D 0; + offset_meas_range_B =3D 0; + sum_ranging_range_B =3D 0; + while ((Status =3D=3D VL53LX_ERROR_NONE) && (inloopcount < Max) && (inlo= opcount < OverMax)) { + Status =3D VL53LX_WaitMeasurementDataReady(Dev); + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData); + pRange =3D &(RangingMeasurementData.RangeData[0]); + goodmeas =3D (pRange->RangeStatus =3D=3D VL53LX_RANGESTATUS_RANGE_VALID= ); + ics =3D pdev->ll_state.cfg_internal_stream_count; + if ((Status =3D=3D VL53LX_ERROR_NONE) && goodmeas) { + if (ics & 0x01) { + sum_ranging_range_A +=3D pRange->RangeMilliMeter; + offset_meas_range_A++; + } else { + sum_ranging_range_B +=3D pRange->RangeMilliMeter; + offset_meas_range_B++; + } + inloopcount =3D offset_meas_range_A + offset_meas_range_B; + } + Status =3D VL53LX_ClearInterruptAndStartMeasurement(Dev); + } + if (inloopcount < UnderMax) + Status =3D VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL; + + VL53LX_StopMeasurement(Dev); + + if ((sum_ranging_range_A < 0) || + (sum_ranging_range_B < 0) || + (sum_ranging_range_A > + ((int32_t) offset_meas_range_A * 0xffff)) || + (sum_ranging_range_B > + ((int32_t) offset_meas_range_B * 0xffff))) { + Status =3D VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH; + } + + if ((Status =3D=3D VL53LX_ERROR_NONE) && (offset_meas_range_A > 0)) { + IncRounding =3D offset_meas_range_A / 2; + meanDistance_mm =3D (int16_t)((sum_ranging_range_A + IncRounding) / off= set_meas_range_A); + offsetA[Repeat] =3D (int16_t)CalDistanceMilliMeter - meanDistance_mm; + } + + if ((Status =3D=3D VL53LX_ERROR_NONE) && (offset_meas_range_B > 0)) { + IncRounding =3D offset_meas_range_B / 2; + meanDistance_mm =3D (int16_t)((sum_ranging_range_B + IncRounding) / off= set_meas_range_B); + offsetB[Repeat] =3D (int16_t)CalDistanceMilliMeter - meanDistance_mm; + } + Repeat++; + } + + if ((SmudgeStatus =3D=3D VL53LX_ERROR_NONE) && (smudge_corr_en =3D=3D 1)) + SmudgeStatus =3D VL53LX_dynamic_xtalk_correction_enable(Dev); + + if (Status =3D=3D VL53LX_ERROR_NONE) { + pdev->per_vcsel_cal_data.short_a_offset_mm =3D offsetA[0]; + pdev->per_vcsel_cal_data.short_b_offset_mm =3D offsetB[0]; + pdev->per_vcsel_cal_data.medium_a_offset_mm =3D offsetA[1]; + pdev->per_vcsel_cal_data.medium_b_offset_mm =3D offsetB[1]; + pdev->per_vcsel_cal_data.long_a_offset_mm =3D offsetA[2]; + pdev->per_vcsel_cal_data.long_b_offset_mm =3D offsetB[2]; + } + + VL53LX_SetDistanceMode(Dev, currentDist); + return Status; +} + +static int ctrl_perform_per_vcsel_calibration_offset_lock(struct stmvl53lx= _data *data, struct stmvl53lx_ioctl_perform_calibration_t *calib) +{ + int rc =3D 0; + + data->is_delay_allowed =3D 1; + + rc =3D stmvl53lx_sendparams(data); + if (rc) + goto done; + + rc =3D VL53LX_PerformOffsetPerVcselCalibration(&data->stdev, calib->param= 1); + data->is_delay_allowed =3D 0; + if (rc) { + vl53lx_errmsg( + "VL53LX_PerformOffsetPerVcselCalibration fail =3D> %d", rc); + rc =3D store_last_error(data, rc); + } + +done: + return rc; +} + +VL53LX_Error VL53LX_PerformOffsetZeroDistanceCalibration(VL53LX_DEV Dev) +{ + #define START_OFFSET 50 + VL53LX_Error Status =3D VL53LX_ERROR_NONE; + int32_t sum_ranging; + uint8_t offset_meas; + int16_t Max, UnderMax, OverMax, Repeat; + int32_t total_count, inloopcount; + int32_t IncRounding; + int16_t meanDistance_mm; + int16_t offset, ZeroDistanceOffset; + VL53LX_MultiRangingData_t RangingMeasurementData; + VL53LX_LLDriverData_t *pdev; + uint8_t goodmeas; + VL53LX_Error SmudgeStatus =3D VL53LX_ERROR_NONE; + uint8_t smudge_corr_en; + VL53LX_TargetRangeData_t *pRange; + + pdev =3D VL53LXDevStructGetLLDriverHandle(Dev); + smudge_corr_en =3D pdev->smudge_correct_config.smudge_corr_enabled; + SmudgeStatus =3D VL53LX_dynamic_xtalk_correction_disable(Dev); + pdev->customer.algo__part_to_part_range_offset_mm =3D 0; + pdev->customer.mm_config__inner_offset_mm =3D START_OFFSET; + pdev->customer.mm_config__outer_offset_mm =3D START_OFFSET; + memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data)); + ZeroDistanceOffset =3D BDTable[VL53LX_TUNING_ZERO_DISTANCE_OFFSET_NON_LIN= EAR_FACTOR]; + Repeat =3D BDTable[VL53LX_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT]; + Max =3D BDTable[VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER= ]; + UnderMax =3D 1 + (Max / 2); + OverMax =3D Max + (Max / 2); + sum_ranging =3D 0; + total_count =3D 0; + + while ((Repeat > 0) && (Status =3D=3D VL53LX_ERROR_NONE)) { + Status =3D VL53LX_StartMeasurement(Dev); + if (Status =3D=3D VL53LX_ERROR_NONE) { + VL53LX_WaitMeasurementDataReady(Dev); + VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData); + VL53LX_ClearInterruptAndStartMeasurement(Dev); + } + inloopcount =3D 0; + offset_meas =3D 0; + while ((Status =3D=3D VL53LX_ERROR_NONE) && (inloopcount < Max) && (offs= et_meas < OverMax)) { + Status =3D VL53LX_WaitMeasurementDataReady(Dev); + if (Status =3D=3D VL53LX_ERROR_NONE) + Status =3D VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData); + pRange =3D &(RangingMeasurementData.RangeData[0]); + goodmeas =3D (pRange->RangeStatus =3D=3D VL53LX_RANGESTATUS_RANGE_VALID= ); + if ((Status =3D=3D VL53LX_ERROR_NONE) && goodmeas) { + sum_ranging =3D sum_ranging + pRange->RangeMilliMeter; + inloopcount++; + } + Status =3D VL53LX_ClearInterruptAndStartMeasurement(Dev); + offset_meas++; + } + total_count +=3D inloopcount; + if (inloopcount < UnderMax) + Status =3D VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL; + VL53LX_StopMeasurement(Dev); + Repeat--; + } + if ((SmudgeStatus =3D=3D VL53LX_ERROR_NONE) && (smudge_corr_en =3D=3D 1)) + SmudgeStatus =3D VL53LX_dynamic_xtalk_correction_enable(Dev); + if ((sum_ranging < 0) || (sum_ranging > ((int32_t) total_count * 0xffff))) + Status =3D VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH; + + if ((Status =3D=3D VL53LX_ERROR_NONE) && (total_count > 0)) { + IncRounding =3D total_count / 2; + meanDistance_mm =3D (int16_t)((sum_ranging + IncRounding) / total_count); + offset =3D START_OFFSET - meanDistance_mm + ZeroDistanceOffset; + pdev->customer.algo__part_to_part_range_offset_mm =3D 0; + pdev->customer.mm_config__inner_offset_mm =3D offset; + pdev->customer.mm_config__outer_offset_mm =3D offset; + Status =3D VL53LX_set_customer_nvm_managed(Dev, &(pdev->customer)); + } + + return Status; +} + +static int ctrl_perform_zero_distance_calibration_offset_lock(struct stmvl= 53lx_data *data, struct stmvl53lx_ioctl_perform_calibration_t *calib) +{ + int rc =3D 0; + + data->is_delay_allowed =3D 1; + + rc =3D stmvl53lx_sendparams(data); + if (rc) + goto done; + + rc =3D VL53LX_PerformOffsetZeroDistanceCalibration(&data->stdev); + data->is_delay_allowed =3D 0; + if (rc) { + vl53lx_errmsg( + "VL53LX_PerformOffsetZeroDistanceCalibration fail =3D> %d", rc); + rc =3D store_last_error(data, rc); + } + +done: + return rc; +} + +static int ctrl_perform_calibration(struct stmvl53lx_data *data, void __us= er *p) +{ + int rc =3D 0; + struct stmvl53lx_ioctl_perform_calibration_t calib; + + mutex_lock(&data->work_mutex); + + if (data->is_device_remove) { + rc =3D -ENODEV; + goto done; + } + data->is_calibrating =3D true; + rc =3D copy_from_user(&calib, p, sizeof(calib)); + if (rc) { + rc =3D -EFAULT; + goto done; + } + if (data->enable_sensor) { + rc =3D -EBUSY; + vl53lx_errmsg("can't perform calibration while ranging\n"); + goto done; + } + + rc =3D reset_release(data); + if (rc) + goto done; + + switch (calib.calibration_type) { + case VL53LX_CALIBRATION_REF_SPAD: + rc =3D ctrl_perform_calibration_ref_spad_lock(data, &calib); + break; + case VL53LX_CALIBRATION_CROSSTALK: + rc =3D ctrl_perform_calibration_crosstalk_lock(data, &calib); + break; + case VL53LX_CALIBRATION_OFFSET: + rc =3D ctrl_perform_simple_calibration_offset_lock(data, &calib); + break; + case VL53LX_CALIBRATION_OFFSET_SIMPLE: + rc =3D ctrl_perform_simple_calibration_offset_lock(data, &calib); + break; + case VL53LX_CALIBRATION_OFFSET_PER_VCSEL: + rc =3D ctrl_perform_per_vcsel_calibration_offset_lock(data, &calib); + break; + case VL53LX_CALIBRATION_OFFSET_ZERO_DISTANCE: + rc =3D ctrl_perform_zero_distance_calibration_offset_lock(data, + &calib); + break; + default: + rc =3D -EINVAL; + break; + } + reset_hold(data); + +done: + data->is_calibrating =3D false; + data->is_first_start_done =3D true; + mutex_unlock(&data->work_mutex); + + return rc; +} + +static int ctrl_mz_data_additional(struct stmvl53lx_data *data, void __use= r *p) +{ + return ctrl_mz_data_common(data, p, true); +} + +static int ctrl_mz_data_blocking_additional(struct stmvl53lx_data *data, v= oid __user *p) +{ + return ctrl_mz_data_blocking_common(data, p, true); +} + +static int stmvl53lx_ioctl_handler(struct stmvl53lx_data *data, unsigned i= nt cmd, unsigned long arg, void __user *p) +{ + int rc =3D 0; + + if (!data) + return -EINVAL; + + switch (cmd) { + case VL53LX_IOCTL_START: + vl53lx_dbgmsg("VL53LX_IOCTL_START\n"); + rc =3D ctrl_start(data); + break; + case VL53LX_IOCTL_STOP: + vl53lx_dbgmsg("VL53LX_IOCTL_STOP\n"); + rc =3D ctrl_stop(data); + break; + case VL53LX_IOCTL_REGISTER: + vl53lx_dbgmsg("VL53LX_IOCTL_REGISTER\n"); + rc =3D ctrl_reg_access(data, p); + break; + case VL53LX_IOCTL_PARAMETER: + vl53lx_dbgmsg("VL53LX_IOCTL_PARAMETER\n"); + rc =3D ctrl_params(data, p); + break; + case VL53LX_IOCTL_ROI: + vl53lx_dbgmsg("VL53LX_IOCTL_ROI\n"); + rc =3D ctrl_roi(data, p); + break; + case VL53LX_IOCTL_MZ_DATA: + rc =3D ctrl_mz_data(data, p); + break; + case VL53LX_IOCTL_MZ_DATA_BLOCKING: + rc =3D ctrl_mz_data_blocking(data, p); + break; + case VL53LX_IOCTL_CALIBRATION_DATA: + vl53lx_dbgmsg("VL53LX_IOCTL_CALIBRATION_DATA\n"); + rc =3D ctrl_calibration_data(data, p); + break; + case VL53LX_IOCTL_PERFORM_CALIBRATION: + vl53lx_dbgmsg("VL53LX_IOCTL_PERFORM_CALIBRATION\n"); + rc =3D ctrl_perform_calibration(data, p); + break; + case VL53LX_IOCTL_MZ_DATA_ADDITIONAL: + rc =3D ctrl_mz_data_additional(data, p); + break; + case VL53LX_IOCTL_MZ_DATA_ADDITIONAL_BLOCKING: + rc =3D ctrl_mz_data_blocking_additional(data, p); + break; + default: + rc =3D -EINVAL; + break; + } + return rc; +} + +static long stmvl53lx_ioctl(struct file *file, unsigned int cmd, unsigned = long arg) +{ + long ret; + struct stmvl53lx_data *data =3D container_of(file->private_data, struct s= tmvl53lx_data, miscdev); + ret =3D stmvl53lx_ioctl_handler(data, cmd, arg, (void __user *)arg); + return ret; +} + +static int stmvl53lx_open(struct inode *inode, struct file *file) +{ + struct stmvl53lx_data *data =3D container_of(file->private_data, struct s= tmvl53lx_data, miscdev); + + vl53lx_dbgmsg("Start\n"); + stmvl53lx_module_func_tbl.get(data->client_object); + vl53lx_dbgmsg("End\n"); + + return 0; +} + +static int stmvl53lx_release(struct inode *inode, struct file *file) +{ + struct stmvl53lx_data *data =3D container_of(file->private_data, struct s= tmvl53lx_data, miscdev); + + vl53lx_dbgmsg("Start\n"); + stmvl53lx_module_func_tbl.put(data->client_object); + vl53lx_dbgmsg("End\n"); + + return 0; +} + +static const struct file_operations stmvl53lx_ranging_fops =3D { + .owner =3D THIS_MODULE, + .unlocked_ioctl =3D stmvl53lx_ioctl, + .open =3D stmvl53lx_open, + .release =3D stmvl53lx_release, +}; + +int stmvl53lx_setup(struct stmvl53lx_data *data) +{ + int rc =3D 0; + VL53LX_DeviceInfo_t dev_info; + + vl53lx_dbgmsg("Enter\n"); + + data->id =3D allocate_dev_id(); + if (data->id < 0) { + vl53lx_errmsg("too many device already created"); + return -1; + } + vl53lx_dbgmsg("Dev id %d is @%p\n", data->id, data); + stmvl53lx_dev_table[data->id] =3D data; + + mutex_init(&data->work_mutex); + + INIT_DELAYED_WORK(&data->dwork, stmvl53lx_work_handler); + data->force_device_on_en =3D force_device_on_en_default; + data->reset_state =3D 1; + data->is_calibrating =3D false; + data->last_error =3D VL53LX_ERROR_NONE; + data->is_device_remove =3D false; + + rc =3D stmvl53lx_module_func_tbl.power_up(data->client_object); + if (rc) { + vl53lx_errmsg("%d,error rc %d\n", __LINE__, rc); + goto exit_func_end; + } + + rc =3D reset_release(data); + if (rc) + goto exit_func_end; + + rc =3D stmvl53lx_input_setup(data); + if (rc) + goto exit_func_end; + + INIT_LIST_HEAD(&data->simple_data_reader_list); + INIT_LIST_HEAD(&data->mz_data_reader_list); + init_waitqueue_head(&data->waiter_for_data); + data->is_data_valid =3D false; + + rc =3D sysfs_create_group(&data->input_dev_ps->dev.kobj, &stmvl53lx_attr_= group); + if (rc) { + rc =3D -ENOMEM; + vl53lx_errmsg("%d error:%d\n", __LINE__, rc); + goto exit_unregister_dev_ps; + } + rc =3D sysfs_create_bin_file(&data->input_dev_ps->dev.kobj, + &stmvl53lx_calib_data_attr); + if (rc) { + rc =3D -ENOMEM; + vl53lx_errmsg("%d error:%d\n", __LINE__, rc); + goto exit_unregister_dev_ps; + } + data->enable_sensor =3D 0; + data->poll_delay_ms =3D STMVL53LX_CFG_POLL_DELAY_MS; + data->timing_budget =3D STMVL53LX_CFG_TIMING_BUDGET_US; + data->distance_mode =3D STMVL53LX_CFG_DEFAULT_DISTANCE_MODE; + data->crosstalk_enable =3D STMVL53LX_CFG_DEFAULT_CROSSTALK_ENABLE; + data->offset_correction_mode =3D STMVL53LX_CFG_DEFAULT_OFFSET_CORRECTION_= MODE; + data->smudge_correction_mode =3D STMVL53LX_CFG_DEFAULT_SMUDGE_CORRECTION_= MODE; + data->is_xtalk_value_changed =3D false; + data->is_delay_allowed =3D true; + + rc =3D VL53LX_DataInit(&data->stdev); + data->is_delay_allowed =3D false; + if (rc) { + vl53lx_errmsg("VL53LX_DataInit %d\n", rc); + goto exit_unregister_dev_ps; + } + + rc =3D VL53LX_GetUserROI(&data->stdev, &(data->roi_cfg)); + if (rc) { + vl53lx_errmsg("VL53LX_GetUserROI %d\n", rc); + goto exit_unregister_dev_ps; + } + + rc =3D VL53LX_GetDeviceInfo(&data->stdev, &dev_info); + if (rc) { + vl53lx_errmsg("VL53LX_GetDeviceInfo %d\n", rc); + goto exit_unregister_dev_ps; + } + vl53lx_errmsg("device type %x\n", dev_info.ProductType); + + rc =3D VL53LX_GetOpticalCenter(&data->stdev, &data->optical_offset_x, &da= ta->optical_offset_y); + if (rc) { + vl53lx_errmsg("VL53LX_GetOpticalCenter %d\n", rc); + goto exit_unregister_dev_ps; + } + + rc =3D setup_tunings(data); + if (rc) { + vl53lx_errmsg("setup_tunings %d\n", rc); + goto exit_unregister_dev_ps; + } + + data->poll_mode =3D 0; + rc =3D stmvl53lx_module_func_tbl.start_intr(data->client_object, &data->p= oll_mode); + if (rc < 0) { + vl53lx_errmsg("can't start no intr\n"); + goto exit_unregister_dev_ps; + } + + data->is_first_irq =3D true; + data->is_first_start_done =3D false; + data->is_delay_allowed =3D false; + + data->miscdev.minor =3D MISC_DYNAMIC_MINOR; + if (data->id =3D=3D 0) + strcpy(data->name, VL53LX_MISC_DEV_NAME); + else + sprintf(data->name, "%s%d", VL53LX_MISC_DEV_NAME, data->id); + + data->miscdev.name =3D data->name; + data->miscdev.fops =3D &stmvl53lx_ranging_fops; + vl53lx_errmsg("Misc device registration name:%s\n", data->miscdev.name); + rc =3D misc_register(&data->miscdev); + if (rc !=3D 0) { + vl53lx_errmsg("misc dev reg fail\n"); + goto exit_unregister_dev_ps; + } + reset_hold(data); + return 0; + +exit_unregister_dev_ps: + sysfs_remove_bin_file(&data->input_dev_ps->dev.kobj, + &stmvl53lx_calib_data_attr); + sysfs_remove_group(&data->input_dev_ps->dev.kobj, + &stmvl53lx_attr_group); + input_unregister_device(data->input_dev_ps); + +exit_func_end: + return rc; +} + +static int stmvl53lx_parse_tree(struct device *dev, struct i2c_data *i2c_d= ata) +{ + struct i2c_client *client =3D (struct i2c_client *) i2c_data->client; + int rc =3D 0; + u32 reg; + + i2c_data->vdd =3D NULL; + i2c_data->pwren_gpio =3D -1; + i2c_data->xsdn_gpio =3D -1; + i2c_data->intr_gpio =3D -1; + i2c_data->boot_reg =3D STMVL53LX_SLAVE_ADDR; + if (force_device) { + i2c_data->xsdn_gpio =3D xsdn_gpio_nb; + i2c_data->pwren_gpio =3D pwren_gpio_nb; + i2c_data->intr_gpio =3D intr_gpio_nb; + client->addr =3D i2c_addr_nb; + } else if (dev->of_node) { + i2c_data->vdd =3D devm_regulator_get_optional(dev, "vdd"); + if (IS_ERR(i2c_data->vdd) || i2c_data->vdd =3D=3D NULL) { + i2c_data->vdd =3D NULL; + i2c_data->pwren_gpio =3D of_get_named_gpio(dev->of_node, "pwren-gpio", = 0); + if (i2c_data->pwren_gpio < 0) { + i2c_data->pwren_gpio =3D -1; + vl53lx_wanrmsg("no regulator, nor power gpio =3D> power ctrl disabled"= ); + } + } + + rc =3D of_property_read_u32_array(dev->of_node, "reg", ®, 1); + if (rc) { + vl53lx_wanrmsg("Unable to find reg %d 0x%x", rc, i2c_addr_nb); + reg =3D i2c_addr_nb; + } + client->addr =3D reg; + + i2c_data->xsdn_gpio =3D of_get_named_gpio(dev->of_node, "xsdn-gpio", 0); + if (i2c_data->xsdn_gpio < 0) { + vl53lx_wanrmsg("Unable to find xsdn-gpio %d %d", rc, i2c_data->xsdn_gpi= o); + i2c_data->xsdn_gpio =3D -1; + } + + i2c_data->intr_gpio =3D of_get_named_gpio(dev->of_node, "intr-gpio", 0); + if (i2c_data->intr_gpio < 0) { + vl53lx_wanrmsg("Unable to find intr-gpio %d %d", rc, i2c_data->intr_gpi= o); + i2c_data->intr_gpio =3D -1; + } + + rc =3D of_property_read_u32_array(dev->of_node, "boot-reg", &i2c_data->b= oot_reg, 1); + if (rc) { + vl53lx_wanrmsg("Unable to find boot-reg %d %d", rc, i2c_data->boot_reg); + i2c_data->boot_reg =3D STMVL53LX_SLAVE_ADDR; + } + } + + rc =3D get_xsdn(dev, i2c_data); + if (rc) + goto no_xsdn; + rc =3D get_pwren(dev, i2c_data); + if (rc) + goto no_pwren; + rc =3D get_intr(dev, i2c_data); + if (rc) + goto no_intr; + + return rc; + +no_intr: + put_intr(i2c_data); +no_pwren: + if (i2c_data->vdd) { + regulator_put(i2c_data->vdd); + i2c_data->vdd =3D NULL; + } + put_pwren(i2c_data); +no_xsdn: + put_xsdn(i2c_data); + return rc; +} + +static void stmvl53lx_release_gpios(struct i2c_data *i2c_data) +{ + put_xsdn(i2c_data); + if (i2c_data->vdd) { + regulator_put(i2c_data->vdd); + i2c_data->vdd =3D NULL; + } + put_pwren(i2c_data); + put_intr(i2c_data); +} + +void stmvl53lx_cleanup(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + vl53lx_dbgmsg("enter\n"); + rc =3D _ctrl_stop(data); + if (rc < 0) + vl53lx_errmsg("stop failed %d aborting anyway\n", rc); + + if (data->input_dev_ps) { + vl53lx_dbgmsg("to remove sysfs group\n"); + sysfs_remove_group(&data->input_dev_ps->dev.kobj, + &stmvl53lx_attr_group); + sysfs_remove_bin_file(&data->input_dev_ps->dev.kobj, + &stmvl53lx_calib_data_attr); + + vl53lx_dbgmsg("to unregister input dev\n"); + input_unregister_device(data->input_dev_ps); + } + + if (!IS_ERR(data->miscdev.this_device) && + data->miscdev.this_device !=3D NULL) { + vl53lx_dbgmsg("to unregister misc dev\n"); + misc_deregister(&data->miscdev); + } + + data->force_device_on_en =3D false; + reset_hold(data); + stmvl53lx_module_func_tbl.power_down(data->client_object); + vl53lx_dbgmsg("done\n"); + deallocate_dev_id(data->id); + data->is_device_remove =3D true; +} + +static int stmvl53lx_probe(struct i2c_client *client) +{ + int rc =3D 0; + struct stmvl53lx_data *vl53lx_data =3D NULL; + struct i2c_data *i2c_data =3D NULL; + + vl53lx_dbgmsg("Enter %s : 0x%02x\n", client->name, client->addr); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { + rc =3D -EIO; + return rc; + } + + vl53lx_data =3D kzalloc(sizeof(struct stmvl53lx_data), GFP_KERNEL); + if (!vl53lx_data) { + rc =3D -ENOMEM; + return rc; + } + if (vl53lx_data) { + vl53lx_data->client_object =3D kzalloc(sizeof(struct i2c_data), GFP_KERN= EL); + if (!vl53lx_data) + goto done_freemem; + i2c_data =3D (struct i2c_data *)vl53lx_data->client_object; + } + + i2c_data->client =3D client; + i2c_data->vl53lx_data =3D vl53lx_data; + i2c_data->irq =3D -1; + + rc =3D stmvl53lx_parse_tree(&i2c_data->client->dev, i2c_data); + if (rc) + goto done_freemem; + + i2c_set_clientdata(client, vl53lx_data); + + rc =3D stmvl53lx_setup(vl53lx_data); + if (rc) + goto release_gpios; + vl53lx_dbgmsg("End\n"); + + kref_init(&i2c_data->ref); + + return rc; + +release_gpios: + stmvl53lx_release_gpios(i2c_data); + +done_freemem: + kfree(vl53lx_data); + kfree(i2c_data); + + return -1; +} + +static void stmvl53lx_remove(struct i2c_client *client) +{ + struct stmvl53lx_data *data =3D i2c_get_clientdata(client); + struct i2c_data *i2c_data =3D (struct i2c_data *)data->client_object; + + vl53lx_dbgmsg("Enter\n"); + mutex_lock(&data->work_mutex); + stmvl53lx_cleanup(data); + + stmvl53lx_release_gpios(i2c_data); + + mutex_unlock(&data->work_mutex); + + stmvl53lx_put(data->client_object); + + vl53lx_dbgmsg("End\n"); + + return; +} + +#ifdef CONFIG_PM_SLEEP + +void stmvl53lx_pm_suspend_stop(struct stmvl53lx_data *data) +{ + int rc =3D 0; + + vl53lx_dbgmsg("Enter\n"); + + rc =3D _ctrl_stop(data); + if (rc < 0) + vl53lx_errmsg("stop failed %d aborting anyway\n", rc); + + vl53lx_dbgmsg("done\n"); +} + +static int stmvl53lx_suspend(struct device *dev) +{ + struct stmvl53lx_data *data =3D i2c_get_clientdata(to_i2c_client(dev)); + + vl53lx_dbgmsg("Enter\n"); + mutex_lock(&data->work_mutex); + + stmvl53lx_pm_suspend_stop(data); + + mutex_unlock(&data->work_mutex); + + vl53lx_dbgmsg("End\n"); + + return 0; +} + +static int stmvl53lx_resume(struct device *dev) +{ +#if 0 + struct stmvl53lx_data *data =3D i2c_get_clientdata(to_i2c_client(dev)); + + vl53lx_dbgmsg("Enter\n"); + + mutex_lock(&data->work_mutex); + + /* do nothing user will restart measurements */ + + mutex_unlock(&data->work_mutex); + + vl53lx_dbgmsg("End\n"); +#else + vl53lx_dbgmsg("Enter\n"); + vl53lx_dbgmsg("End\n"); +#endif + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(stmvl53lx_pm_ops, stmvl53lx_suspend, stmvl53lx_re= sume); + +static const struct i2c_device_id stmvl53lx_id[] =3D { + { STMVL53LX_DRV_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, stmvl53lx_id); + +static const struct of_device_id st_stmvl53lx_dt_match[] =3D { + { .compatible =3D "st,vl53l4cx", }, + { }, +}; + +static struct i2c_driver stmvl53lx_driver =3D { + .driver =3D { + .name =3D STMVL53LX_DRV_NAME, + .owner =3D THIS_MODULE, + .of_match_table =3D st_stmvl53lx_dt_match, + .pm =3D &stmvl53lx_pm_ops, + }, + .probe =3D stmvl53lx_probe, + .remove =3D stmvl53lx_remove, + .id_table =3D stmvl53lx_id, + +}; + +static int insert_device(void) +{ + int ret =3D 0; + struct i2c_adapter *adapter; + struct i2c_board_info info =3D { + .type =3D "stmvl53lx", + .addr =3D STMVL53LX_SLAVE_ADDR, + }; + + memset(&info, 0, sizeof(info)); + strcpy(info.type, "stmvl53lx"); + info.addr =3D STMVL53LX_SLAVE_ADDR; + adapter =3D i2c_get_adapter(adapter_nb); + if (!adapter) { + ret =3D -EINVAL; + goto done; + } + + stm_test_i2c_client =3D i2c_new_client_device(adapter, &info); + if (!stm_test_i2c_client) + ret =3D -EINVAL; + +done: + return ret; +} + +static int __init stmvl53lx_init(void) +{ + int rc =3D -1; + + vl53lx_dbgmsg("Enter\n"); + + rc =3D stmvl53lx_module_func_tbl.init(); + + vl53lx_dbgmsg("End %d\n", rc); + + return rc; +} + +static void __exit stmvl53lx_exit(void) +{ + vl53lx_dbgmsg("Enter\n"); + stmvl53lx_module_func_tbl.deinit(NULL); + if (stmvl53lx_module_func_tbl.clean_up !=3D NULL) + stmvl53lx_module_func_tbl.clean_up(); + vl53lx_dbgmsg("End\n"); +} + +int stmvl53lx_init_i2c(void) +{ + int ret =3D 0; + + vl53lx_dbgmsg("Enter\n"); + + ret =3D i2c_add_driver(&stmvl53lx_driver); + if (ret) + vl53lx_errmsg("%d erro ret:%d\n", __LINE__, ret); + + if (!ret && force_device) + ret =3D insert_device(); + + if (ret) + i2c_del_driver(&stmvl53lx_driver); + + vl53lx_dbgmsg("End with rc:%d\n", ret); + + return ret; +} + +void stmvl53lx_exit_i2c(void *i2c_object) +{ + vl53lx_dbgmsg("Enter\n"); + i2c_del_driver(&stmvl53lx_driver); + vl53lx_dbgmsg("End\n"); +} + +int stmvl53lx_power_up_i2c(void *object) +{ + int rc =3D 0; + struct i2c_data *data =3D (struct i2c_data *) object; + + vl53lx_dbgmsg("Enter\n"); + + if (data->vdd) { + rc =3D regulator_enable(data->vdd); + if (rc) { + vl53lx_errmsg("fail to turn on regulator"); + return rc; + } + } else if (data->pwren_gpio !=3D -1) { + gpio_set_value(data->pwren_gpio, 1); + vl53lx_info("slow power on"); + } else + vl53lx_wanrmsg("no power control"); + + return rc; +} + +int stmvl53lx_power_down_i2c(void *i2c_object) +{ + struct i2c_data *data =3D (struct i2c_data *) i2c_object; + int rc =3D 0; + + vl53lx_dbgmsg("Enter\n"); + + if (data->vdd) { + rc =3D regulator_disable(data->vdd); + if (rc) + vl53lx_errmsg("reg disable failed. rc=3D%d\n", + rc); + } else if (data->pwren_gpio !=3D -1) { + gpio_set_value(data->pwren_gpio, 0); + } + vl53lx_dbgmsg("power off"); + + vl53lx_dbgmsg("End\n"); + + return rc; +} + +int stmvl53lx_reset_release_i2c(void *i2c_object) +{ + int rc; + struct i2c_data *data =3D (struct i2c_data *) i2c_object; + + vl53lx_dbgmsg("Enter\n"); + + rc =3D release_reset(data); + if (rc) + goto error; + + data->vl53lx_data->is_delay_allowed =3D true; + rc =3D VL53LX_WaitDeviceBooted(&data->vl53lx_data->stdev); + data->vl53lx_data->is_delay_allowed =3D false; + if (rc) { + gpio_set_value(data->xsdn_gpio, 0); + vl53lx_errmsg("boot fail with error %d", rc); + data->vl53lx_data->last_error =3D rc; + rc =3D -EIO; + } + +error: + vl53lx_dbgmsg("End\n"); + return rc; +} + +int stmvl53lx_reset_hold_i2c(void *i2c_object) +{ + struct i2c_data *data =3D (struct i2c_data *) i2c_object; + + vl53lx_dbgmsg("Enter\n"); + + gpio_set_value(data->xsdn_gpio, 0); + + vl53lx_dbgmsg("End\n"); + return 0; +} + +void stmvl53lx_clean_up_i2c(void) +{ + if (stm_test_i2c_client) { + vl53lx_dbgmsg("to unregister i2c client\n"); + i2c_unregister_device(stm_test_i2c_client); + } +} + +int stmvl53lx_start_intr(void *object, int *poll_mode) +{ + struct i2c_data *i2c_data; + int rc; + + i2c_data =3D (struct i2c_data *)object; + if (i2c_data->irq < 0) { + *poll_mode =3D -1; + return 0; + } + + i2c_data->msg_flag.unhandled_irq_vec =3D 0; + if (i2c_data->io_flag.intr_started) { + *poll_mode =3D 0; + return 0; + } + + vl53lx_dbgmsg("to register_irq:%d\n", i2c_data->irq); + rc =3D request_threaded_irq(i2c_data->irq, NULL, stmvl53lx_irq_handler_i2= c, IRQF_TRIGGER_FALLING|IRQF_ONESHOT, "vl53lx_interrupt", (void *)i2c_data); + if (rc) { + vl53lx_errmsg("fail to req threaded irq rc=3D%d\n", rc); + *poll_mode =3D 0; + } else { + vl53lx_dbgmsg("irq %d now handled\n", i2c_data->irq); + i2c_data->io_flag.intr_started =3D 1; + *poll_mode =3D 0; + } + return rc; +} + +void *stmvl53lx_get(void *object) +{ + struct i2c_data *data =3D (struct i2c_data *) object; + + vl53lx_dbgmsg("Enter\n"); + kref_get(&data->ref); + vl53lx_dbgmsg("End\n"); + + return object; +} + +void stmvl53lx_put(void *object) +{ + struct i2c_data *data =3D (struct i2c_data *) object; + + vl53lx_dbgmsg("Enter\n"); + kref_put(&data->ref, memory_release); + vl53lx_dbgmsg("End\n"); +} + +static struct stmvl53lx_module_fn_t stmvl53lx_module_func_tbl =3D { + .init =3D stmvl53lx_init_i2c, + .deinit =3D stmvl53lx_exit_i2c, + .power_up =3D stmvl53lx_power_up_i2c, + .power_down =3D stmvl53lx_power_down_i2c, + .reset_release =3D stmvl53lx_reset_release_i2c, + .reset_hold =3D stmvl53lx_reset_hold_i2c, + .clean_up =3D stmvl53lx_clean_up_i2c, + .start_intr =3D stmvl53lx_start_intr, + .get =3D stmvl53lx_get, + .put =3D stmvl53lx_put, +}; + +module_init(stmvl53lx_init); +module_exit(stmvl53lx_exit); + +MODULE_AUTHOR("Song Qiang "); +MODULE_DESCRIPTION("ST vl53l4cx ToF ranging sensor driver"); +MODULE_LICENSE("GPL v2"); --=20 2.25.1