lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <tencent_326708D02875274DF25B10B91402B3828606@qq.com>
Date: Sat,  7 Feb 2026 17:42:35 +0800
From: 434779359@...com
To: Jonathan Cameron <jic23@...nel.org>
Cc: David Lechner <dlechner@...libre.com>,
	Nuno Sá <nuno.sa@...log.com>,
	Andy Shevchenko <andy@...nel.org>,
	Liam Girdwood <lgirdwood@...il.com>,
	Mark Brown <broonie@...nel.org>,
	Linus Walleij <linusw@...nel.org>,
	Bartosz Golaszewski <brgl@...nel.org>,
	liufulin <frank.liu@...ot.com>,
	Waqar Hameed <waqar.hameed@...s.com>,
	linux-kernel@...r.kernel.org,
	linux-iio@...r.kernel.org,
	linux-gpio@...r.kernel.org
Subject: [PATCH] tof: Add VL53L4CX TOF drivers

From: liufulin <frank.liu@...ot.com>

This patch adds support for the vl53l4cx tof ic
ICs used in Qualcomm reference designs

Signed-off-by: liufulin <frank.liu@...ot.com>
---
 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.
 
+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)		+= sx9500.o
 obj-$(CONFIG_VCNL3020)		+= vcnl3020.o
 obj-$(CONFIG_VL53L0X_I2C)	+= vl53l0x-i2c.o
 obj-$(CONFIG_AW96103)		+= aw96103.o
+obj-$(CONFIG_VL53L4CX_I2C)	+= vl53l4cx-i2c.o
 
diff --git a/drivers/iio/proximity/vl53l4cx-i2c.c b/drivers/iio/proximity/vl53l4cx-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 <songqiang1304521@...il.com>
+ * Copyright (C) 2020 Ivan Drobyshevskyi <drobyshevskyi@...il.com>
+ *
+ * Datasheet available at
+ * <https://www.st.com/resource/en/datasheet/vl53l0x.pdf>
+ *
+ * Default 7-bit i2c slave address 0x29.
+ *
+ * TODO: FIFO buffer, continuous mode, range selection, sensor ID check.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/miscdevice.h>
+#include <linux/of_gpio.h>
+#include <linux/input.h>
+
+#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__ == __ERROR_STATUS_CHECK__) { \
+				__STATUS__ = 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) = (data))
+
+#define VL53LXDevStructGetLLDriverHandle(Dev) (&VL53LXDevDataGet(Dev, LLData))
+#define VL53LXDevStructGetLLResultsHandle(Dev) (&VL53LXDevDataGet(Dev,\
+		llresults))
+
+#define VL53LX_SETPARAMETERFIELD(Dev, field, value) \
+	(VL53LXDevDataSet(Dev, CurrentParameters.field, value))
+
+#define VL53LX_GETPARAMETERFIELD(Dev, field, variable) \
+	(variable = 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 = 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)&0xFFFF))
+#define VL53LX_FIXPOINT44TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<12))
+
+#define VL53LX_FIXPOINT1616TOFIXPOINT72(Value) ((uint16_t)((Value>>14)&0xFFFF))
+#define VL53LX_FIXPOINT72TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<14))
+
+#define VL53LX_FIXPOINT1616TOFIXPOINT97(Value) ((uint16_t)((Value>>9)&0xFFFF))
+#define VL53LX_FIXPOINT97TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<9))
+
+#define VL53LX_FIXPOINT1616TOFIXPOINT88(Value) ((uint16_t)((Value>>8)&0xFFFF))
+#define VL53LX_FIXPOINT88TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<8))
+
+#define VL53LX_FIXPOINT1616TOFIXPOINT412(Value) ((uint16_t)((Value>>4)&0xFFFF))
+#define VL53LX_FIXPOINT412TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<4))
+
+#define VL53LX_FIXPOINT1616TOFIXPOINT313(Value) ((uint16_t)((Value>>3)&0xFFFF))
+#define VL53LX_FIXPOINT313TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<3))
+
+#define VL53LX_FIXPOINT1616TOFIXPOINT08(Value) ((uint8_t)((Value>>8)&0x00FF))
+#define VL53LX_FIXPOINT08TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<8))
+
+#define VL53LX_FIXPOINT1616TOFIXPOINT53(Value) ((uint8_t)((Value>>13)&0x00FF))
+#define VL53LX_FIXPOINT53TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<13))
+
+#define VL53LX_FIXPOINT1616TOFIXPOINT102(Value) ((uint16_t)((Value>>14)&0x0FFF))
+#define VL53LX_FIXPOINT102TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<14))
+
+#define VL53LX_FIXPOINT1616TOFIXPOINT142(Value) ((uint16_t)((Value>>14)&0xFFFF))
+#define VL53LX_FIXPOINT142TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<14))
+
+#define VL53LX_FIXPOINT1616TOFIXPOINT160(Value) ((uint16_t)((Value>>16)&0xFFFF))
+#define VL53LX_FIXPOINT160TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<16))
+
+#define VL53LX_MAKEUINT16(lsb, msb) ((uint16_t)((((uint16_t)msb)<<8) + (uint16_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 = 2,
+	VL53LX_POLLDELAY_PAR = 10,
+	VL53LX_TIMINGBUDGET_PAR = 11,
+	VL53LX_DISTANCEMODE_PAR = 12,
+	VL53LX_FORCEDEVICEONEN_PAR = 14,
+	VL53LX_LASTERROR_PAR = 15,
+	VL53LX_OFFSETCORRECTIONMODE_PAR = 16,
+	VL53LX_OPTICALCENTER_PAR = 17,
+	VL53LX_TUNING_PAR = 20,
+	VL53LX_SMUDGECORRECTIONMODE_PAR = 21,
+	VL53LX_ISXTALKVALUECHANGED_PAR = 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 0x0098
+#define VL53LX___PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_LO 0x0099
+#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 0x0ED6
+#define VL53LX_PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD0_LO 0x0ED7
+#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 0x0EE0
+#define VL53LX_PPEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_HI 0x0EE0
+#define VL53LX_PPEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_LO 0x0EE1
+#define VL53LX_PREV_SHADOW_RESULT__MM_INNER_ACTUAL_EFFECTIVE_SPADS_SD0 0x0EE2
+#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 0x0EE4
+#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 0x0EEA
+#define VL53LX_PREV_SHADOW_RESULT__PEAK_SIGNAL_COUNT_RATE_MCPS_SD1_LO 0x0EEB
+#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 0x0FBE
+#define VL53LX_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0_LO 0x0FBF
+#define VL53LX_SHPEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 0x0FC0
+#define VL53LX_SHPEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_HI 0x0FC0
+#define VL53LX_SHPEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0_LO 0x0FC1
+#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 0x0FD2
+#define VL53LX_SHADOW_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD1_LO 0x0FD3
+#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                               0x008E
+#define VL53LX_RESULT__HISTOGRAM_BIN_0_1                               0x008F
+#define VL53LX_RESULT__HISTOGRAM_BIN_0_0                               0x0090
+#define VL53LX_RESULT__HISTOGRAM_BIN_23_2                              0x00D3
+#define VL53LX_RESULT__HISTOGRAM_BIN_23_1                              0x00D4
+#define VL53LX_RESULT__HISTOGRAM_BIN_23_0                              0x00D5
+#define VL53LX_RESULT__HISTOGRAM_BIN_23_0_MSB                          0x00D9
+#define VL53LX_RESULT__HISTOGRAM_BIN_23_0_LSB                          0x00DA
+
+#define VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX       VL53LX_RESULT__INTERRUPT_STATUS
+#define VL53LX_HISTOGRAM_BIN_DATA_I2C_SIZE_BYTES  (VL53LX_RESULT__HISTOGRAM_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_DEFAULT \
+((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_DEFAULT \
+((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 0x00C8
+#define VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS 0x00CA
+#define VL53LX_NVM__FMT__ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS 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 0x00F4
+#define VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS 0x00F6
+#define VL53LX_NVM__CUST__ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS 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_OffsetCorrectionModes)  1)
+#define VL53LX_OFFSETCORRECTIONMODE_PERVCSEL ((VL53LX_OffsetCorrectionModes)  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) - 10)
+#define VL53LX_ERROR_GPIO_NOT_EXISTING                 ((VL53LX_Error) - 11)
+#define VL53LX_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED  ((VL53LX_Error) - 12)
+#define VL53LX_ERROR_CONTROL_INTERFACE                 ((VL53LX_Error) - 13)
+#define VL53LX_ERROR_INVALID_COMMAND                   ((VL53LX_Error) - 14)
+#define VL53LX_ERROR_DIVISION_BY_ZERO                  ((VL53LX_Error) - 15)
+#define VL53LX_ERROR_REF_SPAD_INIT                     ((VL53LX_Error) - 16)
+#define VL53LX_ERROR_GPH_SYNC_CHECK_FAIL               ((VL53LX_Error) - 17)
+#define VL53LX_ERROR_STREAM_COUNT_CHECK_FAIL           ((VL53LX_Error) - 18)
+#define VL53LX_ERROR_GPH_ID_CHECK_FAIL                 ((VL53LX_Error) - 19)
+#define VL53LX_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL      ((VL53LX_Error) - 20)
+#define VL53LX_ERROR_ZONE_GPH_ID_CHECK_FAIL            ((VL53LX_Error) - 21)
+#define VL53LX_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL   ((VL53LX_Error) - 22)
+#define VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL ((VL53LX_Error) - 23)
+#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) - 41)
+#define VL53LX_ERROR_PLATFORM_SPECIFIC_START           ((VL53LX_Error) - 60)
+
+#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 = 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 = dev_get_drvdata(dev); \
+	int param; \
+\
+	mutex_lock(&data->work_mutex); \
+	param = 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 = dev_get_drvdata(dev); \
+	int rc = 0; \
+	int param; \
+\
+	mutex_lock(&data->work_mutex); \
+\
+	if (kstrtoint(buf, 0, &param)) { \
+		vl53lx_errmsg("invalid syntax in %s", buf); \
+		rc = -EINVAL; \
+	} else \
+		rc = 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 = 0; \
+\
+	if (param->is_read) { \
+		param->value = data->sysfs_name; \
+		param->status = 0; \
+		vl53lx_dbgmsg("get " info_name " %d", param->value); \
+		rc = 0; \
+	} else { \
+		rc = 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_RESULTS];
+	VL53LX_histogram_bin_data_t histogram_avg_2[VL53LX_MAX_XTALK_RANGE_RESULTS];
+	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] = {
+		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] = {
+};
+
+int stmvl53lx_enable_debug = 1;
+
+static int force_device;
+static int adapter_nb = -1;
+static int xsdn_gpio_nb = -1;
+static int pwren_gpio_nb = -1;
+static int intr_gpio_nb = -1;
+static int i2c_addr_nb = STMVL53LX_SLAVE_ADDR;
+
+static bool force_device_on_en_default = 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 interrupt");
+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_CalibrationData_t *pCalibrationData);
+VL53LX_Error VL53LX_get_device_results(VL53LX_DEV Dev, VL53LX_DeviceResultsLevel device_results_level, VL53LX_range_results_t *prange_results);
+VL53LX_Error VL53LX_poll_for_range_completion(VL53LX_DEV Dev, uint32_t timeout_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_results_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 timeout_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_period_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_config_timeout_us, uint32_t *pmm_config_timeout_us, uint32_t *prange_config_timeout_us);
+uint32_t VL53LX_calc_timeout_mclks(uint32_t timeout_us, uint32_t macro_period_us);
+uint16_t VL53LX_encode_timeout(uint32_t timeout_mclks);
+uint16_t VL53LX_calc_encoded_timeout(uint32_t timeout_us, uint32_t macro_period_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_timing_config_t  *ptiming);
+VL53LX_Error VL53LX_set_timeouts_us(VL53LX_DEV Dev, uint32_t phasecal_config_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 *pdata, uint16_t buf_size, uint8_t *pbuffer);
+VL53LX_Error VL53LX_WriteMulti(VL53LX_DEV pdev, uint16_t index, uint8_t *pdata, uint32_t count);
+VL53LX_Error VL53LX_ReadMulti(VL53LX_DEV pdev, uint16_t index, uint8_t *pdata, 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 *pdata);
+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 *pdata);
+VL53LX_Error VL53LX_set_system_control(VL53LX_DEV Dev, VL53LX_system_control_t *pdata);
+void V53L1_init_zone_results_structure(uint8_t active_zones, VL53LX_zone_results_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, uint32_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_managed_t *pdata, uint16_t buf_size, uint8_t *pbuffer);
+VL53LX_Error VL53LX_set_customer_nvm_managed(VL53LX_DEV Dev, VL53LX_customer_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_offset_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 XTalkCompensationEnable);
+VL53LX_Error VL53LX_get_preset_mode_timing_cfg(VL53LX_DEV Dev, VL53LX_DevicePresetModes device_preset_mode, uint16_t *pdss_config__target_total_rate_mcps, uint32_t *pphasecal_config_timeout_us, uint32_t *pmm_config_timeout_us, 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_DevicePresetModes 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 DistanceMode);
+VL53LX_Error VL53LX_set_offset_correction_mode(VL53LX_DEV Dev, VL53LX_OffsetCorrectionMode offset_cor_mode);
+VL53LX_Error VL53LX_SetOffsetCorrectionMode(VL53LX_DEV Dev, VL53LX_OffsetCorrectionModes 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_DEV 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_DEV Dev);
+VL53LX_Error VL53LX_SmudgeCorrectionEnable(VL53LX_DEV Dev, VL53LX_SmudgeCorrectionModes 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 tuning_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 *pencoded_xy_size);
+VL53LX_Error VL53LX_set_user_zone(VL53LX_DEV Dev, VL53LX_user_zone_t *puser_zone);
+VL53LX_Error VL53LX_set_zone_dss_config(VL53LX_DEV Dev, VL53LX_zone_private_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_managed_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 *pdata, 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 *pdata, 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 *pinternal_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 measurement_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 *pMeasurementDataReady);
+long stmvl53lx_tv_dif(struct st_timeval *pstart_tv, struct st_timeval *pstop_tv);
+VL53LX_Error VL53LX_GetMultiRangingData(VL53LX_DEV Dev, VL53LX_MultiRangingData_t *pMultiRangingData);
+VL53LX_Error VL53LX_get_histogram_debug_data(VL53LX_DEV Dev, VL53LX_histogram_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_AdditionalData_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 tuning_parm_key, int32_t tuning_parm_value);
+VL53LX_Error VL53LX_SetTuningParameter(VL53LX_DEV Dev, uint16_t TuningParameterId, int32_t TuningParameterValue);
+VL53LX_Error VL53LX_GetTuningParameter(VL53LX_DEV Dev, uint16_t TuningParameterId, int32_t *pTuningParameterValue);
+VL53LX_Error VL53LX_set_part_to_part_data(VL53LX_DEV Dev, VL53LX_calibration_data_t *pcal_data);
+VL53LX_Error VL53LX_get_current_xtalk_settings(VL53LX_DEV Dev, VL53LX_xtalk_calibration_results_t *pxtalk);
+VL53LX_Error VL53LX_set_current_xtalk_settings(VL53LX_DEV Dev, VL53LX_xtalk_calibration_results_t *pxtalk);
+VL53LX_Error VL53LX_SetCalibrationData(VL53LX_DEV Dev, VL53LX_CalibrationData_t *pCalibrationData);
+VL53LX_Error VL53LX_get_part_to_part_data(VL53LX_DEV Dev, VL53LX_calibration_data_t *pcal_data);
+void VL53LX_init_version(VL53LX_DEV Dev);
+VL53LX_Error VL53LX_get_static_nvm_managed(VL53LX_DEV Dev, VL53LX_static_nvm_managed_t *pdata);
+VL53LX_Error VL53LX_i2c_decode_customer_nvm_managed(uint16_t buf_size, uint8_t *pbuffer, VL53LX_customer_nvm_managed_t *pdata);
+VL53LX_Error VL53LX_get_customer_nvm_managed(VL53LX_DEV Dev, VL53LX_customer_nvm_managed_t *pdata);
+VL53LX_Error VL53LX_i2c_decode_nvm_copy_data(uint16_t buf_size, uint8_t *pbuffer, 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, uint8_t *pbuffer);
+VL53LX_Error VL53LX_set_firmware_enable_register(VL53LX_DEV Dev, uint8_t value);
+VL53LX_Error VL53LX_disable_firmware(VL53LX_DEV Dev);
+VL53LX_Error VL53LX_nvm_enable(VL53LX_DEV Dev, uint16_t nvm_ctrl_pulse_width, 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_address, 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_size, uint8_t *pbuffer, VL53LX_additional_offset_cal_data_t *pdata);
+VL53LX_Error VL53LX_read_nvm_additional_offset_cal_data(VL53LX_DEV Dev, VL53LX_additional_offset_cal_data_t *pcal_data);
+void VL53LX_spad_number_to_byte_bit_index(uint8_t spad_number, uint8_t *pbyte_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 *pcol);
+void VL53LX_decode_zone_size(uint8_t encoded_xy_size, uint8_t *pwidth, uint8_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, uint8_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_zone_t *pmm_roi);
+VL53LX_Error VL53LX_read_p2p_data(VL53LX_DEV Dev);
+VL53LX_Error VL53LX_init_refspadchar_config_struct(VL53LX_refspadchar_config_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_config_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 *pdata);
+VL53LX_Error VL53LX_init_hist_post_process_config_struct(uint8_t xtalk_compensation_enable, VL53LX_hist_post_process_config_t *pdata);
+VL53LX_Error VL53LX_init_hist_gen3_dmax_config_struct(VL53LX_hist_gen3_dmax_config_t *pdata);
+VL53LX_Error VL53LX_init_tuning_parm_storage_struct(VL53LX_tuning_parm_storage_t *pdata);
+void VL53LX_init_histogram_bin_data_struct(int32_t bin_value, uint16_t VL53LX_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_LLDriverResults_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 dmax_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 *pVL53LX_DeviceInfo);
+VL53LX_Error VL53LX_GetOpticalCenter(VL53LX_DEV Dev, FixPoint1616_t *pOpticalCenterX, 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 *pdata);
+void VL53LX_hist_estimate_ambient_from_ambient_bins(VL53LX_histogram_bin_data_t *pdata);
+VL53LX_Error VL53LX_get_histogram_bin_data(VL53LX_DEV Dev, VL53LX_histogram_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, uint16_t *pmax_effective_spads);
+VL53LX_Error VL53LX_get_dmax_calibration_data(VL53LX_DEV Dev, VL53LX_DeviceDmaxMode dmax_mode, VL53LX_dmax_calibration_data_t *pdmax_cal);
+VL53LX_Error VL53LX_f_031(VL53LX_histogram_bin_data_t *pidata, VL53LX_histogram_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_effective_spads, uint8_t roi_centre_spad, uint8_t roi_xy_size, uint32_t *xtalk_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_histogram_bin_data_t *pxtalkcount_data);
+void VL53LX_copy_xtalk_bin_data_to_histogram_data_struct(VL53LX_xtalk_histogram_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 *pdata);
+uint32_t VL53LX_isqrt(uint32_t num);
+void VL53LX_hist_estimate_ambient_from_thresholded_bins(int32_t ambient_threshold_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_bin_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_spads, uint32_t duration);
+uint32_t VL53LX_f_002(uint32_t events_threshold, uint32_t ref_signal_events, 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 *pbins, 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_histogram_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_range_data_t *pdata);
+VL53LX_Error VL53LX_f_020(int16_t VL53LX_p_019, int16_t VL53LX_p_024, uint8_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_histogram_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, VL53LX_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_count_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 *phistpostprocess, 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_zone_hist_info_t *phist_prev, VL53LX_zone_objects_t *prange_prev, VL53LX_range_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_range_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_results_t *presults);
+void VL53LX_copy_hist_bins_to_static_cfg(VL53LX_histogram_config_t *phistogram, 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 *pbuffer, VL53LX_debug_results_t *pdata);
+VL53LX_Error VL53LX_i2c_decode_core_results(uint16_t buf_size, uint8_t *pbuffer, 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_DeviceResultsLevel 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_status);
+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_bin_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_xtalk_extract_data_t *pxtalk_data);
+VL53LX_Error VL53LX_hist_xtalk_extract_calc_shape(VL53LX_hist_xtalk_extract_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 = now.tv_sec;
+	tv->tv_usec = 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_elapsed_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 = 0;
+
+	i2c_data->io_flag.xsdn_owned = 0;
+	if (i2c_data->xsdn_gpio == -1) {
+		vl53lx_errmsg("reset gpio is required");
+		rc = -ENODEV;
+		goto no_gpio;
+	}
+
+	vl53lx_dbgmsg("request xsdn_gpio %d", i2c_data->xsdn_gpio);
+	rc = gpio_request(i2c_data->xsdn_gpio, "vl53lx_xsdn");
+	if (rc) {
+		vl53lx_errmsg("fail to acquire xsdn %d", rc);
+		goto request_failed;
+	}
+
+	rc = 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 = 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 = 0;
+	}
+	i2c_data->xsdn_gpio = -1;
+}
+
+static int get_pwren(struct device *dev, struct i2c_data *i2c_data)
+{
+	int rc = 0;
+
+	i2c_data->io_flag.pwr_owned = 0;
+	if (i2c_data->pwren_gpio == -1) {
+		vl53lx_wanrmsg("pwren gpio disable");
+		goto no_gpio;
+	}
+
+	vl53lx_dbgmsg("request pwren_gpio %d", i2c_data->pwren_gpio);
+	rc = gpio_request(i2c_data->pwren_gpio, "vl53lx_pwren");
+	if (rc) {
+		vl53lx_errmsg("fail to acquire pwren %d", rc);
+		goto request_failed;
+	}
+
+	rc = 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 = 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 = 0;
+	}
+	i2c_data->pwren_gpio = -1;
+}
+
+static int get_intr(struct device *dev, struct i2c_data *i2c_data)
+{
+	int rc = 0;
+
+	i2c_data->io_flag.intr_owned = 0;
+	if (i2c_data->intr_gpio == -1) {
+		vl53lx_wanrmsg("no interrupt gpio");
+		goto no_gpio;
+	}
+
+	vl53lx_dbgmsg("request intr_gpio %d", i2c_data->intr_gpio);
+	rc = gpio_request(i2c_data->intr_gpio, "vl53lx_intr");
+	if (rc) {
+		vl53lx_errmsg("fail to acquire intr %d", rc);
+		goto request_failed;
+	}
+
+	rc = 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 = 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_gpio, i2c_data->irq);
+		goto irq_failed;
+	}
+	i2c_data->io_flag.intr_owned = 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 = 0;
+		}
+		vl53lx_dbgmsg("release intr_gpio %d", i2c_data->intr_gpio);
+		gpio_free(i2c_data->intr_gpio);
+		i2c_data->io_flag.intr_owned = 0;
+	}
+	i2c_data->intr_gpio = -1;
+}
+
+static int handle_i2c_address_device_change_lock(struct i2c_data *data)
+{
+	struct i2c_client *client = (struct i2c_client *) data->client;
+	uint8_t buffer[3];
+	struct i2c_msg msg;
+	int rc = 0;
+
+	vl53lx_dbgmsg("change device i2c address from 0x%02x to 0x%02x", data->boot_reg, client->addr);
+
+	usleep_range(VL53LX_FIRMWARE_BOOT_TIME_US, VL53LX_FIRMWARE_BOOT_TIME_US + 1);
+
+	buffer[0] = (VL53LX_I2C_SLAVE__DEVICE_ADDRESS >> 8) & 0xFF;
+	buffer[1] = (VL53LX_I2C_SLAVE__DEVICE_ADDRESS >> 0) & 0xFF;
+	buffer[2] = client->addr;
+	msg.addr = data->boot_reg;
+	msg.flags = client->flags;
+	msg.buf = buffer;
+	msg.len = 3;
+	if (i2c_transfer(client->adapter, &msg, 1) != 1) {
+		rc = -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 = (struct i2c_client *) data->client;
+	int rc = 0;
+	bool is_address_change = client->addr != 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 = 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 = (struct stmvl53lx_data *)container_of(pdev, struct stmvl53lx_data, 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 = (struct i2c_data *)dev->client_object;
+	struct i2c_client *client = (struct i2c_client *)i2c_client_obj->client;
+	int rc;
+
+	cci_access_var;
+	if (len > STMVL53LX_MAX_CCI_XFER_SZ || len == 0) {
+		vl53lx_errmsg("invalid len %d\n", len);
+		return -1;
+	}
+	cci_access_start();
+	buffer[0] = (index >> 8) & 0xFF;
+	buffer[1] = (index >> 0) & 0xFF;
+	memcpy(buffer + 2, data, len);
+	msg.addr = client->addr;
+	msg.flags = client->flags;
+	msg.buf = buffer;
+	msg.len = len + 2;
+
+	rc = i2c_transfer(client->adapter, &msg, 1);
+	if (rc != 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 != 1, len);
+	return rc != 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 = (struct i2c_data *)dev->client_object;
+	struct i2c_client *client = (struct i2c_client *)i2c_client_obj->client;
+	int rc;
+
+	cci_access_var;
+	if (len > STMVL53LX_MAX_CCI_XFER_SZ || len == 0) {
+		vl53lx_errmsg("invalid len %d\n", len);
+		return -1;
+	}
+	cci_access_start();
+
+	buffer[0] = (index >> 8) & 0xFF;
+	buffer[1] = (index >> 0) & 0xFF;
+
+	msg[0].addr = client->addr;
+	msg[0].flags = client->flags;
+	msg[0].buf = buffer;
+	msg[0].len = 2;
+
+	msg[1].addr = client->addr;
+	msg[1].flags = I2C_M_RD | client->flags;
+	msg[1].buf = data;
+	msg[1].len = len;
+
+	rc = i2c_transfer(client->adapter, msg, 2);
+	if (rc != 2) {
+		pr_err("%s: i2c_transfer :%d, @%x index 0x%x len %d\n", __func__, rc, client->addr, index, len);
+	}
+	cci_access_over(" wr len %d status %d", rc != 2, len);
+	return rc != 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) / 1000;
+}
+
+static int is_time_over(struct st_timeval *tv, uint32_t msec)
+{
+	return tv_elapsed_ms(tv) >= 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 = (struct stmvl53lx_data *)container_of(pdev, struct stmvl53lx_data, stdev);
+
+	st_gettimeofday(&start_tv);
+	do {
+		rc = cci_read(dev, index, &rd_val, 1);
+		if (rc)
+			return VL53LX_ERROR_CONTROL_INTERFACE;
+		if ((rd_val & mask) == value) {
+			poll_timing_log(&start_tv);
+			return VL53LX_ERROR_NONE;
+		}
+		vl53lx_dbgmsg("poll @%x %x & %d != %x", index, rd_val, mask, value);
+		time_over = 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 = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state);
+
+	pstate->cfg_device_state  = device_state;
+	pstate->cfg_stream_count  = 0;
+	pstate->cfg_gph_id        = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
+	pstate->cfg_timing_status = 0;
+	pstate->cfg_zone_id       = 0;
+
+	pstate->rd_device_state   = device_state;
+	pstate->rd_stream_count   = 0;
+	pstate->rd_gph_id         = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
+	pstate->rd_timing_status  = 0;
+	pstate->rd_zone_id        = 0;
+}
+
+VL53LX_Error VL53LX_poll_for_boot_completion(VL53LX_DEV Dev, uint32_t timeout_ms)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	status = VL53LX_WaitUs(Dev, VL53LX_FIRMWARE_BOOT_TIME_US);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WaitValueMaskEx(Dev, timeout_ms, VL53LX_FIRMWARE__SYSTEM_STATUS, 0x01, 0x01, VL53LX_POLLING_DELAY_MS);
+
+	if (status == 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 = VL53LX_ERROR_NONE;
+
+	Status = VL53LX_poll_for_boot_completion(Dev, VL53LX_BOOT_COMPLETION_POLLING_TIMEOUT_MS);
+
+	return Status;
+}
+
+static int stmvl53lx_input_setup(struct stmvl53lx_data *data)
+{
+	int rc = 0;
+	struct input_dev *idev;
+	idev = input_allocate_device();
+	if (idev == NULL) {
+		rc = -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 = "STM VL53LX proximity sensor";
+	rc = input_register_device(idev);
+	if (rc) {
+		rc = -ENOMEM;
+		vl53lx_errmsg("%d error:%d\n", __LINE__, rc);
+		goto exit_free_dev_ps;
+	}
+	input_set_drvdata(idev, data);
+	data->input_dev_ps = 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 = 0;
+
+	if (fast_osc_frequency > 0)
+		pll_period_us = (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 = 0;
+
+	VL53LX_p_030 = (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        = 0;
+	uint8_t   VL53LX_p_030   = 0;
+	uint32_t  macro_period_us      = 0;
+
+	pll_period_us = VL53LX_calc_pll_period_us(fast_osc_frequency);
+
+	VL53LX_p_030 = VL53LX_decode_vcsel_period(VL53LX_p_005);
+
+	macro_period_us = (uint32_t)VL53LX_MACRO_PERIOD_VCSEL_PERIODS * pll_period_us;
+	macro_period_us = macro_period_us >> 6;
+
+	macro_period_us = macro_period_us * (uint32_t)VL53LX_p_030;
+	macro_period_us = macro_period_us >> 6;
+
+	return macro_period_us;
+}
+
+uint32_t VL53LX_calc_timeout_us(uint32_t timeout_mclks, uint32_t macro_period_us)
+{
+	uint32_t timeout_us     = 0;
+	uint64_t tmp            = 0;
+
+
+	tmp  = (uint64_t)timeout_mclks * (uint64_t)macro_period_us;
+	tmp += 0x00800;
+	tmp  = tmp >> 12;
+
+	timeout_us = (uint32_t)tmp;
+
+	return timeout_us;
+}
+
+uint32_t VL53LX_decode_timeout(uint16_t encoded_timeout)
+{
+	uint32_t timeout_macro_clks = 0;
+
+	timeout_macro_clks = ((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  = 0;
+	uint32_t timeout_us     = 0;
+
+	timeout_mclks = VL53LX_decode_timeout(timeout_encoded);
+
+	timeout_us = VL53LX_calc_timeout_us(timeout_mclks, macro_period_us);
+
+	return timeout_us;
+}
+
+VL53LX_Error VL53LX_get_timeouts_us(VL53LX_DEV Dev, uint32_t *pphasecal_config_timeout_us, uint32_t *pmm_config_timeout_us, uint32_t *prange_config_timeout_us)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	uint32_t  macro_period_us = 0;
+	uint16_t  timeout_encoded = 0;
+
+	if (pdev->stat_nvm.osc_measured__fast_osc__frequency == 0)
+		status = VL53LX_ERROR_DIVISION_BY_ZERO;
+
+	if (status == VL53LX_ERROR_NONE) {
+		macro_period_us = VL53LX_calc_macro_period_us(pdev->stat_nvm.osc_measured__fast_osc__frequency, pdev->tim_cfg.range_config__vcsel_period_a);
+
+		*pphasecal_config_timeout_us = VL53LX_calc_timeout_us((uint32_t)pdev->gen_cfg.phasecal_config__timeout_macrop, macro_period_us);
+
+		timeout_encoded = (uint16_t)pdev->tim_cfg.mm_config__timeout_macrop_a_hi;
+		timeout_encoded = (timeout_encoded << 8) + (uint16_t)pdev->tim_cfg.mm_config__timeout_macrop_a_lo;
+
+		*pmm_config_timeout_us = VL53LX_calc_decoded_timeout_us(timeout_encoded, macro_period_us);
+
+		timeout_encoded = (uint16_t)pdev->tim_cfg.range_config__timeout_macrop_a_hi;
+		timeout_encoded = (timeout_encoded << 8) + (uint16_t)pdev->tim_cfg.range_config__timeout_macrop_a_lo;
+
+		*prange_config_timeout_us = VL53LX_calc_decoded_timeout_us(timeout_encoded, macro_period_us);
+
+		pdev->phasecal_config_timeout_us = *pphasecal_config_timeout_us;
+		pdev->mm_config_timeout_us       = *pmm_config_timeout_us;
+		pdev->range_config_timeout_us    = *prange_config_timeout_us;
+
+	}
+
+	return status;
+}
+
+uint32_t VL53LX_calc_timeout_mclks(uint32_t timeout_us, uint32_t macro_period_us)
+{
+	uint32_t timeout_mclks   = 0;
+
+	if (macro_period_us == 0)
+		timeout_mclks = 0;
+	else
+		timeout_mclks = ((timeout_us << 12) + (macro_period_us>>1)) / macro_period_us;
+
+	return timeout_mclks;
+}
+
+uint16_t VL53LX_encode_timeout(uint32_t timeout_mclks)
+{
+	uint16_t encoded_timeout = 0;
+	uint32_t ls_byte = 0;
+	uint16_t ms_byte = 0;
+
+	if (timeout_mclks > 0) {
+		ls_byte = timeout_mclks - 1;
+		while ((ls_byte & 0xFFFFFF00) > 0) {
+			ls_byte = ls_byte >> 1;
+			ms_byte++;
+		}
+		encoded_timeout = (ms_byte << 8) + (uint16_t) (ls_byte & 0x000000FF);
+	}
+	return encoded_timeout;
+}
+
+
+uint16_t VL53LX_calc_encoded_timeout(uint32_t timeout_us, uint32_t macro_period_us)
+{
+	uint32_t timeout_mclks   = 0;
+	uint16_t timeout_encoded = 0;
+
+	timeout_mclks = VL53LX_calc_timeout_mclks(timeout_us, macro_period_us);
+
+	timeout_encoded = 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_timing_config_t  *ptiming)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	uint32_t macro_period_us    = 0;
+	uint32_t timeout_mclks      = 0;
+	uint16_t timeout_encoded    = 0;
+
+	if (fast_osc_frequency == 0) {
+		status = VL53LX_ERROR_DIVISION_BY_ZERO;
+	} else {
+		macro_period_us = VL53LX_calc_macro_period_us(fast_osc_frequency, ptiming->range_config__vcsel_period_a);
+
+		timeout_mclks = VL53LX_calc_timeout_mclks(phasecal_config_timeout_us, macro_period_us);
+
+		if (timeout_mclks > 0xFF)
+			timeout_mclks = 0xFF;
+
+		pgeneral->phasecal_config__timeout_macrop = (uint8_t)timeout_mclks;
+
+		timeout_encoded = VL53LX_calc_encoded_timeout(mm_config_timeout_us, macro_period_us);
+
+		ptiming->mm_config__timeout_macrop_a_hi = (uint8_t)((timeout_encoded & 0xFF00) >> 8);
+		ptiming->mm_config__timeout_macrop_a_lo = (uint8_t) (timeout_encoded & 0x00FF);
+
+		timeout_encoded = VL53LX_calc_encoded_timeout(range_config_timeout_us, macro_period_us);
+
+		ptiming->range_config__timeout_macrop_a_hi = (uint8_t)((timeout_encoded & 0xFF00) >> 8);
+		ptiming->range_config__timeout_macrop_a_lo = (uint8_t) (timeout_encoded & 0x00FF);
+
+		macro_period_us = VL53LX_calc_macro_period_us(fast_osc_frequency, ptiming->range_config__vcsel_period_b);
+
+		timeout_encoded = VL53LX_calc_encoded_timeout(mm_config_timeout_us, macro_period_us);
+
+		ptiming->mm_config__timeout_macrop_b_hi = (uint8_t)((timeout_encoded & 0xFF00) >> 8);
+		ptiming->mm_config__timeout_macrop_b_lo = (uint8_t) (timeout_encoded & 0x00FF);
+
+		timeout_encoded = VL53LX_calc_encoded_timeout(range_config_timeout_us, macro_period_us);
+
+		ptiming->range_config__timeout_macrop_b_hi = (uint8_t)((timeout_encoded & 0xFF00) >> 8);
+		ptiming->range_config__timeout_macrop_b_lo = (uint8_t) (timeout_encoded & 0x00FF);
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_set_timeouts_us(VL53LX_DEV Dev, uint32_t phasecal_config_timeout_us, uint32_t mm_config_timeout_us, uint32_t range_config_timeout_us)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	if (pdev->stat_nvm.osc_measured__fast_osc__frequency == 0)
+		status = VL53LX_ERROR_DIVISION_BY_ZERO;
+
+	if (status == VL53LX_ERROR_NONE) {
+		pdev->phasecal_config_timeout_us = phasecal_config_timeout_us;
+		pdev->mm_config_timeout_us       = mm_config_timeout_us;
+		pdev->range_config_timeout_us    = range_config_timeout_us;
+
+		status = VL53LX_calc_timeout_register_values(phasecal_config_timeout_us, mm_config_timeout_us, range_config_timeout_us, pdev->stat_nvm.osc_measured__fast_osc__frequency, &(pdev->gen_cfg), &(pdev->tim_cfg));
+	}
+	return status;
+}
+
+static int IsL4(VL53LX_DEV Dev)
+{
+	int devL4 = 0;
+	VL53LX_LLDriverData_t *pDev;
+	pDev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	if ((pDev->nvm_copy_data.identification__module_type == 0xAA) && (pDev->nvm_copy_data.identification__model_id == 0xEB))
+		devL4 = 1;
+	return devL4;
+}
+
+VL53LX_Error VL53LX_SetMeasurementTimingBudgetMicroSeconds(VL53LX_DEV Dev, uint32_t MeasurementTimingBudgetMicroSeconds)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	uint32_t TimingGuard;
+	uint32_t divisor;
+	uint32_t TimingBudget = 0;
+	uint32_t MmTimeoutUs = 0;
+	uint32_t PhaseCalTimeoutUs = 0;
+	uint32_t FDAMaxTimingBudgetUs = FDA_MAX_TIMING_BUDGET_US;
+
+	if (MeasurementTimingBudgetMicroSeconds > 10000000)
+		Status = VL53LX_ERROR_INVALID_PARAMS;
+
+	if (Status == VL53LX_ERROR_NONE)
+		Status = VL53LX_get_timeouts_us(Dev, &PhaseCalTimeoutUs, &MmTimeoutUs, &TimingBudget);
+
+	TimingGuard = 1700;
+	divisor = 6;
+
+	if (IsL4(Dev))
+		FDAMaxTimingBudgetUs = L4_FDA_MAX_TIMING_BUDGET_US;
+
+	if (MeasurementTimingBudgetMicroSeconds <= TimingGuard)
+		Status = VL53LX_ERROR_INVALID_PARAMS;
+	else {
+		TimingBudget = (MeasurementTimingBudgetMicroSeconds - TimingGuard);
+	}
+
+	if (Status == VL53LX_ERROR_NONE) {
+		if (TimingBudget > FDAMaxTimingBudgetUs)
+			Status = VL53LX_ERROR_INVALID_PARAMS;
+		else {
+			TimingBudget /= divisor;
+			Status = VL53LX_set_timeouts_us(Dev, PhaseCalTimeoutUs, MmTimeoutUs, TimingBudget);
+		}
+		if (Status == VL53LX_ERROR_NONE)
+			VL53LXDevDataSet(Dev, LLData.range_config_timeout_us, TimingBudget);
+	}
+	if (Status == VL53LX_ERROR_NONE) {
+		VL53LXDevDataSet(Dev, CurrentParameters.MeasurementTimingBudgetMicroSeconds, MeasurementTimingBudgetMicroSeconds);
+	}
+	return Status;
+}
+
+static int store_last_error(struct stmvl53lx_data *data, int rc)
+{
+	data->last_error = rc;
+
+	return -EIO;
+}
+
+VL53LX_Error VL53LX_i2c_encode_system_control(VL53LX_system_control_t *pdata, uint16_t buf_size, uint8_t *pbuffer)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (buf_size < VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES)
+		return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
+
+	*(pbuffer + 0) = pdata->power_management__go1_power_force & 0x1;
+	*(pbuffer + 1) = pdata->system__stream_count_ctrl & 0x1;
+	*(pbuffer + 2) = pdata->firmware__enable & 0x1;
+	*(pbuffer + 3) = pdata->system__interrupt_clear & 0x3;
+	*(pbuffer + 4) = pdata->system__mode_start;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_WriteMulti(VL53LX_DEV pdev, uint16_t index, uint8_t *pdata, uint32_t count)
+{
+	uint32_t chunk_size = WRITE_MULTIPLE_CHUNK_MAX;
+	VL53LX_Error status;
+	uint32_t i;
+	uint16_t hostaddr = index;
+	struct stmvl53lx_data *dev;
+
+	dev = (struct stmvl53lx_data *)container_of(pdev, struct stmvl53lx_data, stdev);
+
+	for (i = 0; i < count; i += chunk_size) {
+		status = (cci_write(dev, hostaddr, &pdata[i],  min(chunk_size, (count - i))) ? VL53LX_ERROR_CONTROL_INTERFACE : VL53LX_ERROR_NONE);
+		if (status != VL53LX_ERROR_NONE)
+			break;
+		hostaddr += chunk_size;
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_ReadMulti(VL53LX_DEV pdev, uint16_t index, uint8_t *pdata, uint32_t count)
+{
+	struct stmvl53lx_data *dev;
+
+	dev = (struct stmvl53lx_data *)container_of(pdev, struct stmvl53lx_data, stdev);
+
+	return cci_read(dev, index, pdata, count) ? VL53LX_ERROR_CONTROL_INTERFACE : VL53LX_ERROR_NONE;
+}
+
+VL53LX_Error VL53LX_RdByte(VL53LX_DEV pdev, uint16_t index, uint8_t *pdata)
+{
+	struct stmvl53lx_data *dev;
+	dev = (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 = (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 *pdata)
+{
+	VL53LX_Error status;
+	uint8_t buffer[2];
+
+	status = VL53LX_ReadMulti(pdev, index, buffer, 2);
+
+	*pdata = ((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] = (uint8_t) (data >> 8);
+	buffer[1] = (uint8_t) (data & 0x00FF);
+	i2c_debug(" @%x d= %x  => [ %x , %x ] ", index, data, buffer[0], buffer[1]);
+	status = VL53LX_WriteMulti(pdev, index, buffer, 2);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_WrDWord(VL53LX_DEV pdev, uint16_t index, uint32_t data)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint8_t buffer[4];
+
+	buffer[0] = (uint8_t) (data >> 24);
+	buffer[1] = (uint8_t) ((data & 0x00FF0000) >> 16);
+	buffer[2] = (uint8_t) ((data & 0x0000FF00) >> 8);
+	buffer[3] = (uint8_t) (data & 0x000000FF);
+
+	status = VL53LX_WriteMulti(pdev, index, buffer, 4);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_RdDWord(VL53LX_DEV pdev, uint16_t index, uint32_t *pdata)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint8_t buffer[4];
+
+	status = VL53LX_ReadMulti(pdev, index, buffer, 4);
+
+	*pdata = ((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_control_t *pdata)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint8_t comms_buffer[VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES];
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_i2c_encode_system_control(pdata, VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES, comms_buffer);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WriteMulti(Dev, VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE, comms_buffer, VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES);
+
+	return status;
+}
+
+void V53L1_init_zone_results_structure(uint8_t active_zones, VL53LX_zone_results_t *pdata)
+{
+	uint8_t  z = 0;
+	VL53LX_zone_objects_t *pobjects;
+
+	pdata->max_zones    = VL53LX_MAX_USER_ZONES;
+	pdata->active_zones = active_zones;
+
+	for (z = 0; z < pdata->max_zones; z++) {
+		pobjects = &(pdata->VL53LX_p_003[z]);
+		pobjects->cfg_device_state = VL53LX_DEVICESTATE_SW_STANDBY;
+		pobjects->rd_device_state  = VL53LX_DEVICESTATE_SW_STANDBY;
+		pobjects->max_objects      = VL53LX_MAX_RANGE_RESULTS;
+		pobjects->active_objects   = 0;
+	}
+}
+
+void V53L1_init_zone_dss_configs(VL53LX_DEV Dev)
+{
+	VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+	uint8_t  z = 0;
+	uint8_t max_zones    = VL53LX_MAX_USER_ZONES;
+	VL53LX_zone_private_dyn_cfgs_t *pdata = &(pres->zone_dyn_cfgs);
+
+	for (z = 0; z < max_zones; z++) {
+		pdata->VL53LX_p_003[z].dss_mode = VL53LX_DSS_CONTROL__MODE_TARGET_RATE;
+		pdata->VL53LX_p_003[z].dss_requested_effective_spad_count = 0;
+	}
+}
+
+VL53LX_Error VL53LX_low_power_auto_data_stop_range(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->low_power_auto_data.low_power_auto_range_count = 0xFF;
+
+	pdev->low_power_auto_data.first_run_phasecal_result = 0;
+	pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0;
+	pdev->low_power_auto_data.dss__required_spads = 0;
+
+	if (pdev->low_power_auto_data.saved_vhv_init != 0)
+		pdev->stat_nvm.vhv_config__init = pdev->low_power_auto_data.saved_vhv_init;
+	if (pdev->low_power_auto_data.saved_vhv_timeout != 0)
+		pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound = pdev->low_power_auto_data.saved_vhv_timeout;
+
+	pdev->gen_cfg.phasecal_config__override = 0x00;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_stop_range(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+
+	pdev->sys_ctrl.system__mode_start = (pdev->sys_ctrl.system__mode_start & VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK) | VL53LX_DEVICEMEASUREMENTMODE_ABORT;
+
+	status = VL53LX_set_system_control(Dev, &pdev->sys_ctrl);
+
+	pdev->sys_ctrl.system__mode_start = (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 == 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       = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->sys_ctrl.power_management__go1_power_force = value;
+
+	status = VL53LX_WrByte(Dev, VL53LX_POWER_MANAGEMENT__GO1_POWER_FORCE, pdev->sys_ctrl.power_management__go1_power_force);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_disable_powerforce(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	status = VL53LX_set_powerforce_register(Dev, 0x00);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_unload_patch(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x00);
+
+	if (status == VL53LX_ERROR_NONE)
+		VL53LX_disable_powerforce(Dev);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_PATCH__CTRL, 0x00);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x01);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_StopMeasurement(VL53LX_DEV Dev)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+
+	Status = 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 = 0;
+
+	rc = VL53LX_StopMeasurement(&data->stdev);
+	if (rc) {
+		vl53lx_errmsg("VL53LX_StopMeasurement @%d fail %d", __LINE__, rc);
+		rc = store_last_error(data, rc);
+	}
+
+	reset_hold(data);
+	data->enable_sensor = 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    = 0;
+	uint16_t VL53LX_p_003 = 0;
+
+	VL53LX_p_003 = ip_value;
+
+	for (i = 0; i < count; i++) {
+		pbuffer[count-i-1] = (uint8_t)(VL53LX_p_003 & 0x00FF);
+		VL53LX_p_003 = VL53LX_p_003 >> 8;
+	}
+}
+
+uint16_t VL53LX_i2c_decode_uint16_t(uint16_t count, uint8_t *pbuffer)
+{
+	uint16_t   value = 0x00;
+
+	while (count-- > 0)
+		value = (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 = 0;
+	int16_t VL53LX_p_003 = 0;
+
+	VL53LX_p_003 = ip_value;
+
+	for (i = 0; i < count; i++) {
+		pbuffer[count-i-1] = (uint8_t)(VL53LX_p_003 & 0x00FF);
+		VL53LX_p_003 = VL53LX_p_003 >> 8;
+	}
+}
+
+int16_t VL53LX_i2c_decode_int16_t(uint16_t count, uint8_t *pbuffer)
+{
+	int16_t    value = 0x00;
+
+	if (*pbuffer >= 0x80)
+		value = 0xFFFF;
+
+	while (count-- > 0)
+		value = (value << 8) | (int16_t)*pbuffer++;
+
+	return value;
+}
+
+uint32_t VL53LX_i2c_decode_with_mask(uint16_t count, uint8_t *pbuffer, uint32_t bit_mask, uint32_t down_shift, uint32_t offset)
+{
+	uint32_t   value = 0x00;
+
+	while (count-- > 0)
+		value = (value << 8) | (uint32_t)*pbuffer++;
+
+	value =  value & bit_mask;
+	if (down_shift > 0)
+		value = value >> down_shift;
+
+	value = value + offset;
+
+	return value;
+}
+
+
+void VL53LX_i2c_encode_int32_t(int32_t ip_value, uint16_t count, uint8_t *pbuffer)
+{
+	uint16_t   i    = 0;
+	int32_t    VL53LX_p_003 = 0;
+
+	VL53LX_p_003 =  ip_value;
+
+	for (i = 0; i < count; i++) {
+		pbuffer[count-i-1] = (uint8_t)(VL53LX_p_003 & 0x00FF);
+		VL53LX_p_003 = VL53LX_p_003 >> 8;
+	}
+}
+
+int32_t VL53LX_i2c_decode_int32_t(uint16_t count, uint8_t *pbuffer)
+{
+	int32_t    value = 0x00;
+
+	if (*pbuffer >= 0x80)
+		value = 0xFFFFFFFF;
+
+	while (count-- > 0)
+		value = (value << 8) | (int32_t)*pbuffer++;
+
+	return value;
+}
+
+VL53LX_Error VL53LX_i2c_encode_customer_nvm_managed(VL53LX_customer_nvm_managed_t *pdata, uint16_t buf_size, uint8_t *pbuffer)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (buf_size < VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES)
+		return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
+
+	*(pbuffer +   0) = pdata->global_config__spad_enables_ref_0;
+	*(pbuffer +   1) = pdata->global_config__spad_enables_ref_1;
+	*(pbuffer +   2) = pdata->global_config__spad_enables_ref_2;
+	*(pbuffer +   3) = pdata->global_config__spad_enables_ref_3;
+	*(pbuffer +   4) = pdata->global_config__spad_enables_ref_4;
+	*(pbuffer +   5) = pdata->global_config__spad_enables_ref_5 & 0xF;
+	*(pbuffer +   6) = pdata->global_config__ref_en_start_select;
+	*(pbuffer +   7) = pdata->ref_spad_man__num_requested_ref_spads & 0x3F;
+	*(pbuffer +   8) = pdata->ref_spad_man__ref_location & 0x3;
+	VL53LX_i2c_encode_uint16_t(pdata->algo__crosstalk_compensation_plane_offset_kcps, 2, pbuffer + 9);
+	VL53LX_i2c_encode_int16_t(pdata->algo__crosstalk_compensation_x_plane_gradient_kcps, 2, pbuffer + 11);
+	VL53LX_i2c_encode_int16_t(pdata->algo__crosstalk_compensation_y_plane_gradient_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 & 0x1FFF, 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_customer_nvm_managed_t *pdata)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint8_t comms_buffer[VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES];
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_i2c_encode_customer_nvm_managed(pdata, VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES, comms_buffer);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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 = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
+	VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
+
+	pN->algo__crosstalk_compensation_plane_offset_kcps = 0x00;
+	pN->algo__crosstalk_compensation_x_plane_gradient_kcps = 0x00;
+	pN->algo__crosstalk_compensation_y_plane_gradient_kcps = 0x00;
+	pdev->xtalk_cfg.global_crosstalk_compensation_enable = 0x00;
+	pHP->algo__crosstalk_compensation_enable = pdev->xtalk_cfg.global_crosstalk_compensation_enable;
+
+	if (status == VL53LX_ERROR_NONE) {
+		pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps = 0x0000;
+	}
+	if (status == VL53LX_ERROR_NONE) {
+		status = VL53LX_set_customer_nvm_managed(Dev, &(pdev->customer));
+	}
+	return status;
+}
+
+uint32_t VL53LX_calc_crosstalk_plane_offset_with_margin(uint32_t plane_offset_kcps, int16_t margin_offset_kcps)
+{
+	uint32_t plane_offset_with_margin = 0;
+	int32_t  plane_offset_kcps_temp   = 0;
+
+	plane_offset_kcps_temp = (int32_t)plane_offset_kcps + (int32_t)margin_offset_kcps;
+
+	if (plane_offset_kcps_temp < 0)
+		plane_offset_kcps_temp = 0;
+	else
+		if (plane_offset_kcps_temp > 0x3FFFF)
+			plane_offset_kcps_temp = 0x3FFFF;
+
+	plane_offset_with_margin = (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  = 0;
+	uint16_t   range_ignore_thresh_kcps = 0;
+	int32_t    central_rate_int         = 0;
+	int16_t    x_gradient_int           = 0;
+	int16_t    y_gradient_int           = 0;
+
+	central_rate_int = ((int32_t)central_rate * (1 << 4)) / (1000);
+
+	if (x_gradient < 0)
+		x_gradient_int = x_gradient * -1;
+
+	if (y_gradient < 0)
+		y_gradient_int = y_gradient * -1;
+
+
+	range_ignore_thresh_int = (8 * x_gradient_int * 4) + (8 * y_gradient_int * 4);
+	range_ignore_thresh_int = range_ignore_thresh_int / 1000;
+	range_ignore_thresh_int = range_ignore_thresh_int + central_rate_int;
+	range_ignore_thresh_int = (int32_t)rate_mult * range_ignore_thresh_int;
+	range_ignore_thresh_int = (range_ignore_thresh_int + (1<<4)) / (1<<5);
+
+	if (range_ignore_thresh_int > 0xFFFF)
+		range_ignore_thresh_kcps = 0xFFFF;
+	else
+		range_ignore_thresh_kcps = (uint16_t)range_ignore_thresh_int;
+
+	return range_ignore_thresh_kcps;
+}
+
+VL53LX_Error VL53LX_enable_xtalk_compensation(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint32_t tempu32;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
+	VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
+	VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
+
+	tempu32 = VL53LX_calc_crosstalk_plane_offset_with_margin(pC->algo__crosstalk_compensation_plane_offset_kcps, pC->lite_mode_crosstalk_margin_kcps);
+	if (tempu32 > 0xFFFF)
+		tempu32 = 0xFFFF;
+
+	pN->algo__crosstalk_compensation_plane_offset_kcps = (uint16_t)tempu32;
+	pN->algo__crosstalk_compensation_x_plane_gradient_kcps = pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
+	pN->algo__crosstalk_compensation_y_plane_gradient_kcps = pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
+	pHP->algo__crosstalk_compensation_plane_offset_kcps = VL53LX_calc_crosstalk_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 = pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
+	pHP->algo__crosstalk_compensation_y_plane_gradient_kcps = pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
+	pC->global_crosstalk_compensation_enable = 0x01;
+	pHP->algo__crosstalk_compensation_enable = pC->global_crosstalk_compensation_enable;
+
+	if (status == VL53LX_ERROR_NONE) {
+		pC->crosstalk_range_ignore_threshold_rate_mcps =
+		VL53LX_calc_range_ignore_threshold(pC->algo__crosstalk_compensation_plane_offset_kcps, pC->algo__crosstalk_compensation_x_plane_gradient_kcps, pC->algo__crosstalk_compensation_y_plane_gradient_kcps, pC->crosstalk_range_ignore_threshold_mult);
+	}
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_set_customer_nvm_managed(Dev, &(pdev->customer));
+
+	return status;
+}
+
+VL53LX_Error VL53LX_SetXTalkCompensationEnable(VL53LX_DEV Dev, uint8_t XTalkCompensationEnable)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+
+	if (XTalkCompensationEnable == 0)
+		Status = VL53LX_disable_xtalk_compensation(Dev);
+	else
+		Status = VL53LX_enable_xtalk_compensation(Dev);
+
+	return Status;
+}
+
+static VL53LX_Error ComputeDevicePresetMode(VL53LX_DistanceModes DistanceMode, VL53LX_DevicePresetModes *pDevicePresetMode)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+
+	uint8_t DistIdx;
+	VL53LX_DevicePresetModes RangingModes[3] = { VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE, VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE, VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE};
+
+	switch (DistanceMode) {
+	case VL53LX_DISTANCEMODE_SHORT:
+		DistIdx = 0;
+		break;
+	case VL53LX_DISTANCEMODE_MEDIUM:
+		DistIdx = 1;
+		break;
+	default:
+		DistIdx = 2;
+	}
+	*pDevicePresetMode = RangingModes[DistIdx];
+	return Status;
+}
+
+VL53LX_Error VL53LX_get_preset_mode_timing_cfg(VL53LX_DEV Dev, VL53LX_DevicePresetModes device_preset_mode, uint16_t *pdss_config__target_total_rate_mcps, uint32_t *pphasecal_config_timeout_us, uint32_t *pmm_config_timeout_us, uint32_t  *prange_config_timeout_us)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	switch (device_preset_mode) {
+	case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE:
+		*pdss_config__target_total_rate_mcps = pdev->tuning_parms.tp_dss_target_histo_mcps;
+		*pphasecal_config_timeout_us = pdev->tuning_parms.tp_phasecal_timeout_hist_long_us;
+		*pmm_config_timeout_us = pdev->tuning_parms.tp_mm_timeout_histo_us;
+		*prange_config_timeout_us = pdev->tuning_parms.tp_range_timeout_histo_us;
+		break;
+	case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE:
+		*pdss_config__target_total_rate_mcps = pdev->tuning_parms.tp_dss_target_histo_mcps;
+		*pphasecal_config_timeout_us = pdev->tuning_parms.tp_phasecal_timeout_hist_med_us;
+		*pmm_config_timeout_us = pdev->tuning_parms.tp_mm_timeout_histo_us;
+		*prange_config_timeout_us = pdev->tuning_parms.tp_range_timeout_histo_us;
+		break;
+	case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE:
+		*pdss_config__target_total_rate_mcps = pdev->tuning_parms.tp_dss_target_histo_mcps;
+		*pphasecal_config_timeout_us = pdev->tuning_parms.tp_phasecal_timeout_hist_short_us;
+		*pmm_config_timeout_us = pdev->tuning_parms.tp_mm_timeout_histo_us;
+		*prange_config_timeout_us = pdev->tuning_parms.tp_range_timeout_histo_us;
+		break;
+	default:
+		status = 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 = VL53LX_ERROR_NONE;
+
+	pstatic->dss_config__target_total_rate_mcps = 0x0A00;
+	pstatic->debug__ctrl = 0x00;
+	pstatic->test_mode__ctrl = 0x00;
+	pstatic->clk_gating__ctrl = 0x00;
+	pstatic->nvm_bist__ctrl = 0x00;
+	pstatic->nvm_bist__num_nvm_words = 0x00;
+	pstatic->nvm_bist__start_address = 0x00;
+	pstatic->host_if__status = 0x00;
+	pstatic->pad_i2c_hv__config = 0x00;
+	pstatic->pad_i2c_hv__extsup_config = 0x00;
+	pstatic->gpio_hv_pad__ctrl = 0x00;
+	pstatic->gpio_hv_mux__ctrl = VL53LX_DEVICEINTERRUPTPOLARITY_ACTIVE_LOW | VL53LX_DEVICEGPIOMODE_OUTPUT_RANGE_AND_ERROR_INTERRUPTS;
+	pstatic->gpio__tio_hv_status = 0x02;
+	pstatic->gpio__fio_hv_status = 0x00;
+	pstatic->ana_config__spad_sel_pswidth = 0x02;
+	pstatic->ana_config__vcsel_pulse_width_offset = 0x08;
+	pstatic->ana_config__fast_osc__config_ctrl = 0x00;
+	pstatic->sigma_estimator__effective_pulse_width_ns = ptuning_parms->tp_lite_sigma_est_pulse_width_ns;
+	pstatic->sigma_estimator__effective_ambient_width_ns = ptuning_parms->tp_lite_sigma_est_amb_width_ns;
+	pstatic->sigma_estimator__sigma_ref_mm = ptuning_parms->tp_lite_sigma_ref_mm;
+	pstatic->algo__crosstalk_compensation_valid_height_mm = 0x01;
+	pstatic->spare_host_config__static_config_spare_0 = 0x00;
+	pstatic->spare_host_config__static_config_spare_1 = 0x00;
+	pstatic->algo__range_ignore_threshold_mcps = 0x0000;
+	pstatic->algo__range_ignore_valid_height_mm = 0xff;
+	pstatic->algo__range_min_clip = ptuning_parms->tp_lite_min_clip;
+	pstatic->algo__consistency_check__tolerance = ptuning_parms->tp_consistency_lite_phase_tolerance;
+	pstatic->spare_host_config__static_config_spare_2 = 0x00;
+	pstatic->sd_config__reset_stages_msb = 0x00;
+	pstatic->sd_config__reset_stages_lsb = 0x00;
+	pgeneral->gph_config__stream_count_update_value = 0x00;
+	pgeneral->global_config__stream_divider = 0x00;
+	pgeneral->system__interrupt_config_gpio = VL53LX_INTERRUPT_CONFIG_NEW_SAMPLE_READY;
+	pgeneral->cal_config__vcsel_start = 0x0B;
+	pgeneral->cal_config__repeat_rate = ptuning_parms->tp_cal_repeat_rate;
+	pgeneral->global_config__vcsel_width = 0x02;
+	pgeneral->phasecal_config__timeout_macrop = 0x0D;
+	pgeneral->phasecal_config__target = ptuning_parms->tp_phasecal_target;
+	pgeneral->phasecal_config__override = 0x00;
+	pgeneral->dss_config__roi_mode_control = VL53LX_DEVICEDSSMODE__TARGET_RATE;
+	pgeneral->system__thresh_rate_high = 0x0000;
+	pgeneral->system__thresh_rate_low = 0x0000;
+	pgeneral->dss_config__manual_effective_spads_select = 0x8C00;
+	pgeneral->dss_config__manual_block_select = 0x00;
+	pgeneral->dss_config__aperture_attenuation = 0x38;
+	pgeneral->dss_config__max_spads_limit = 0xFF;
+	pgeneral->dss_config__min_spads_limit = 0x01;
+	ptiming->mm_config__timeout_macrop_a_hi = 0x00;
+	ptiming->mm_config__timeout_macrop_a_lo = 0x1a;
+	ptiming->mm_config__timeout_macrop_b_hi = 0x00;
+	ptiming->mm_config__timeout_macrop_b_lo = 0x20;
+	ptiming->range_config__timeout_macrop_a_hi = 0x01;
+	ptiming->range_config__timeout_macrop_a_lo = 0xCC;
+	ptiming->range_config__vcsel_period_a = 0x0B;
+	ptiming->range_config__timeout_macrop_b_hi = 0x01;
+	ptiming->range_config__timeout_macrop_b_lo = 0xF5;
+	ptiming->range_config__vcsel_period_b = 0x09;
+	ptiming->range_config__sigma_thresh = ptuning_parms->tp_lite_med_sigma_thresh_mm;
+	ptiming->range_config__min_count_rate_rtn_limit_mcps = ptuning_parms->tp_lite_med_min_count_rate_rtn_mcps;
+	ptiming->range_config__valid_phase_low = 0x08;
+	ptiming->range_config__valid_phase_high = 0x78;
+	ptiming->system__intermeasurement_period = 0x00000000;
+	ptiming->system__fractional_enable = 0x00;
+	phistogram->histogram_config__low_amb_even_bin_0_1 = 0x07;
+	phistogram->histogram_config__low_amb_even_bin_2_3 = 0x21;
+	phistogram->histogram_config__low_amb_even_bin_4_5 = 0x43;
+	phistogram->histogram_config__low_amb_odd_bin_0_1 = 0x10;
+	phistogram->histogram_config__low_amb_odd_bin_2_3 = 0x32;
+	phistogram->histogram_config__low_amb_odd_bin_4_5 = 0x54;
+	phistogram->histogram_config__mid_amb_even_bin_0_1 = 0x07;
+	phistogram->histogram_config__mid_amb_even_bin_2_3 = 0x21;
+	phistogram->histogram_config__mid_amb_even_bin_4_5 = 0x43;
+	phistogram->histogram_config__mid_amb_odd_bin_0_1 = 0x10;
+	phistogram->histogram_config__mid_amb_odd_bin_2 = 0x02;
+	phistogram->histogram_config__mid_amb_odd_bin_3_4 = 0x43;
+	phistogram->histogram_config__mid_amb_odd_bin_5 = 0x05;
+	phistogram->histogram_config__user_bin_offset = 0x00;
+	phistogram->histogram_config__high_amb_even_bin_0_1 = 0x07;
+	phistogram->histogram_config__high_amb_even_bin_2_3 = 0x21;
+	phistogram->histogram_config__high_amb_even_bin_4_5 = 0x43;
+	phistogram->histogram_config__high_amb_odd_bin_0_1 = 0x10;
+	phistogram->histogram_config__high_amb_odd_bin_2_3 = 0x32;
+	phistogram->histogram_config__high_amb_odd_bin_4_5 = 0x54;
+	phistogram->histogram_config__amb_thresh_low = 0xFFFF;
+	phistogram->histogram_config__amb_thresh_high = 0xFFFF;
+	phistogram->histogram_config__spad_array_selection = 0x00;
+	pzone_cfg->max_zones                     = VL53LX_MAX_USER_ZONES;
+	pzone_cfg->active_zones = 0x00;
+	pzone_cfg->user_zones[0].height = 0x0f;
+	pzone_cfg->user_zones[0].width = 0x0f;
+	pzone_cfg->user_zones[0].x_centre = 0x08;
+	pzone_cfg->user_zones[0].y_centre = 0x08;
+	pdynamic->system__grouped_parameter_hold_0 = 0x01;
+	pdynamic->system__thresh_high = 0x0000;
+	pdynamic->system__thresh_low = 0x0000;
+	pdynamic->system__enable_xtalk_per_quadrant = 0x00;
+	pdynamic->system__seed_config = ptuning_parms->tp_lite_seed_cfg;
+	pdynamic->sd_config__woi_sd0 = 0x0B;
+	pdynamic->sd_config__woi_sd1 = 0x09;
+	pdynamic->sd_config__initial_phase_sd0 = ptuning_parms->tp_init_phase_rtn_lite_med;
+	pdynamic->sd_config__initial_phase_sd1 = ptuning_parms->tp_init_phase_ref_lite_med;
+	pdynamic->system__grouped_parameter_hold_1 = 0x01;
+	pdynamic->sd_config__first_order_select = ptuning_parms->tp_lite_first_order_select;
+	pdynamic->sd_config__quantifier = ptuning_parms->tp_lite_quantifier;
+	pdynamic->roi_config__user_roi_centre_spad = 0xC7;
+	pdynamic->roi_config__user_roi_requested_global_xy_size = 0xFF;
+	pdynamic->system__sequence_config = VL53LX_SEQUENCE_VHV_EN | VL53LX_SEQUENCE_PHASECAL_EN | VL53LX_SEQUENCE_DSS1_EN | VL53LX_SEQUENCE_DSS2_EN | VL53LX_SEQUENCE_MM2_EN | VL53LX_SEQUENCE_RANGE_EN;
+	pdynamic->system__grouped_parameter_hold = 0x02;
+	psystem->system__stream_count_ctrl = 0x00;
+	psystem->firmware__enable = 0x01;
+	psystem->system__interrupt_clear = VL53LX_CLEAR_RANGE_INT;
+	psystem->system__mode_start = VL53LX_DEVICESCHEDULERMODE_STREAMING | VL53LX_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 = (even_bin1 << 4) + even_bin0;
+	pdata->histogram_config__low_amb_even_bin_2_3 = (even_bin3 << 4) + even_bin2;
+	pdata->histogram_config__low_amb_even_bin_4_5 = (even_bin5 << 4) + even_bin4;
+	pdata->histogram_config__low_amb_odd_bin_0_1 = (odd_bin1 << 4) + odd_bin0;
+	pdata->histogram_config__low_amb_odd_bin_2_3 = (odd_bin3 << 4) + odd_bin2;
+	pdata->histogram_config__low_amb_odd_bin_4_5 = (odd_bin5 << 4) + odd_bin4;
+	pdata->histogram_config__mid_amb_even_bin_0_1 = pdata->histogram_config__low_amb_even_bin_0_1;
+	pdata->histogram_config__mid_amb_even_bin_2_3 = pdata->histogram_config__low_amb_even_bin_2_3;
+	pdata->histogram_config__mid_amb_even_bin_4_5 = pdata->histogram_config__low_amb_even_bin_4_5;
+	pdata->histogram_config__mid_amb_odd_bin_0_1 = pdata->histogram_config__low_amb_odd_bin_0_1;
+	pdata->histogram_config__mid_amb_odd_bin_2 = odd_bin2;
+	pdata->histogram_config__mid_amb_odd_bin_3_4 = (odd_bin4 << 4) + odd_bin3;
+	pdata->histogram_config__mid_amb_odd_bin_5 = odd_bin5;
+	pdata->histogram_config__user_bin_offset = 0x00;
+	pdata->histogram_config__high_amb_even_bin_0_1 = pdata->histogram_config__low_amb_even_bin_0_1;
+	pdata->histogram_config__high_amb_even_bin_2_3 = pdata->histogram_config__low_amb_even_bin_2_3;
+	pdata->histogram_config__high_amb_even_bin_4_5 = pdata->histogram_config__low_amb_even_bin_4_5;
+	pdata->histogram_config__high_amb_odd_bin_0_1 = pdata->histogram_config__low_amb_odd_bin_0_1;
+	pdata->histogram_config__high_amb_odd_bin_2_3 = pdata->histogram_config__low_amb_odd_bin_2_3;
+	pdata->histogram_config__high_amb_odd_bin_4_5 = pdata->histogram_config__low_amb_odd_bin_4_5;
+	pdata->histogram_config__amb_thresh_low = 0xFFFF;
+	pdata->histogram_config__amb_thresh_high = 0xFFFF;
+	pdata->histogram_config__spad_array_selection = 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 = (even_bin1 << 4) + even_bin0;
+	pdata->histogram_config__low_amb_even_bin_2_3 = (even_bin3 << 4) + even_bin2;
+	pdata->histogram_config__low_amb_even_bin_4_5 = (even_bin5 << 4) + even_bin4;
+	pdata->histogram_config__low_amb_odd_bin_0_1 = pdata->histogram_config__low_amb_even_bin_0_1;
+	pdata->histogram_config__low_amb_odd_bin_2_3 = pdata->histogram_config__low_amb_even_bin_2_3;
+	pdata->histogram_config__low_amb_odd_bin_4_5 = pdata->histogram_config__low_amb_even_bin_4_5;
+	pdata->histogram_config__mid_amb_even_bin_0_1 = pdata->histogram_config__low_amb_even_bin_0_1;
+	pdata->histogram_config__mid_amb_even_bin_2_3 = pdata->histogram_config__low_amb_even_bin_2_3;
+	pdata->histogram_config__mid_amb_even_bin_4_5 = pdata->histogram_config__low_amb_even_bin_4_5;
+	pdata->histogram_config__mid_amb_odd_bin_0_1 = pdata->histogram_config__low_amb_odd_bin_0_1;
+	pdata->histogram_config__mid_amb_odd_bin_2 = odd_bin2;
+	pdata->histogram_config__mid_amb_odd_bin_3_4 = (odd_bin4 << 4) + odd_bin3;
+	pdata->histogram_config__mid_amb_odd_bin_5 = odd_bin5;
+	pdata->histogram_config__user_bin_offset = 0x00;
+	pdata->histogram_config__high_amb_even_bin_0_1 = (odd_bin1 << 4) + odd_bin0;
+	pdata->histogram_config__high_amb_even_bin_2_3 = (odd_bin3 << 4) + odd_bin2;
+	pdata->histogram_config__high_amb_even_bin_4_5 = (odd_bin5 << 4) + odd_bin4;
+	pdata->histogram_config__high_amb_odd_bin_0_1 = pdata->histogram_config__high_amb_even_bin_0_1;
+	pdata->histogram_config__high_amb_odd_bin_2_3 = pdata->histogram_config__high_amb_even_bin_2_3;
+	pdata->histogram_config__high_amb_odd_bin_4_5 = pdata->histogram_config__high_amb_even_bin_4_5;
+	pdata->histogram_config__amb_thresh_low = 0xFFFF;
+	pdata->histogram_config__amb_thresh_high = 0xFFFF;
+	pdata->histogram_config__spad_array_selection = 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 = phistogram->histogram_config__high_amb_even_bin_0_1;
+	pstatic->sigma_estimator__effective_ambient_width_ns = phistogram->histogram_config__high_amb_even_bin_2_3;
+	pstatic->sigma_estimator__sigma_ref_mm = phistogram->histogram_config__high_amb_even_bin_4_5;
+	pstatic->algo__crosstalk_compensation_valid_height_mm = phistogram->histogram_config__high_amb_odd_bin_0_1;
+	pstatic->spare_host_config__static_config_spare_0 = phistogram->histogram_config__high_amb_odd_bin_2_3;
+	pstatic->spare_host_config__static_config_spare_1 = phistogram->histogram_config__high_amb_odd_bin_4_5;
+	pstatic->algo__range_ignore_threshold_mcps = (((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 = phistogram->histogram_config__mid_amb_even_bin_4_5;
+	pstatic->algo__range_min_clip = phistogram->histogram_config__mid_amb_odd_bin_0_1;
+	pstatic->algo__consistency_check__tolerance = phistogram->histogram_config__mid_amb_odd_bin_2;
+	pstatic->spare_host_config__static_config_spare_2 = phistogram->histogram_config__mid_amb_odd_bin_3_4;
+	pstatic->sd_config__reset_stages_msb = phistogram->histogram_config__mid_amb_odd_bin_5;
+	pstatic->sd_config__reset_stages_lsb = phistogram->histogram_config__user_bin_offset;
+	ptiming->range_config__sigma_thresh = (((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 = (((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 = phistogram->histogram_config__low_amb_odd_bin_2_3;
+	ptiming->range_config__valid_phase_high = phistogram->histogram_config__low_amb_odd_bin_4_5;
+	pdynamic->system__thresh_high = phistogram->histogram_config__amb_thresh_low;
+	pdynamic->system__thresh_low = phistogram->histogram_config__amb_thresh_high;
+	pdynamic->system__enable_xtalk_per_quadrant = phistogram->histogram_config__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 = VL53LX_ERROR_NONE;
+
+	status = VL53LX_preset_mode_standard_ranging(pstatic, phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cfg);
+	if (status == VL53LX_ERROR_NONE) {
+		pstatic->dss_config__target_total_rate_mcps = 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 = 0x09;
+		ptiming->range_config__vcsel_period_b = 0x0B;
+		pdynamic->sd_config__woi_sd0 = 0x09;
+		pdynamic->sd_config__woi_sd1 = 0x0B;
+		ptiming->mm_config__timeout_macrop_a_hi = 0x00;
+		ptiming->mm_config__timeout_macrop_a_lo = 0x20;
+		ptiming->mm_config__timeout_macrop_b_hi = 0x00;
+		ptiming->mm_config__timeout_macrop_b_lo = 0x1A;
+		ptiming->range_config__timeout_macrop_a_hi = 0x00;
+		ptiming->range_config__timeout_macrop_a_lo = 0x28;
+		ptiming->range_config__timeout_macrop_b_hi = 0x00;
+		ptiming->range_config__timeout_macrop_b_lo = 0x21;
+		pgeneral->phasecal_config__timeout_macrop = 0xF5;
+		phistpostprocess->valid_phase_low = 0x08;
+		phistpostprocess->valid_phase_high = 0x88;
+		VL53LX_copy_hist_cfg_to_static_cfg(phistogram, pstatic, pgeneral, ptiming, pdynamic);
+		pdynamic->system__sequence_config = VL53LX_SEQUENCE_VHV_EN | VL53LX_SEQUENCE_PHASECAL_EN | VL53LX_SEQUENCE_DSS1_EN | VL53LX_SEQUENCE_DSS2_EN | VL53LX_SEQUENCE_RANGE_EN;
+		psystem->system__mode_start = VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | VL53LX_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 = VL53LX_ERROR_NONE;
+
+	status = VL53LX_preset_mode_histogram_ranging(phistpostprocess, pstatic, phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cfg);
+	if (status == 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, ptiming, pdynamic);
+		ptiming->range_config__vcsel_period_a = 0x09;
+		ptiming->range_config__vcsel_period_b = 0x0b;
+		ptiming->mm_config__timeout_macrop_a_hi = 0x00;
+		ptiming->mm_config__timeout_macrop_a_lo = 0x21;
+		ptiming->mm_config__timeout_macrop_b_hi = 0x00;
+		ptiming->mm_config__timeout_macrop_b_lo = 0x1b;
+		ptiming->range_config__timeout_macrop_a_hi = 0x00;
+		ptiming->range_config__timeout_macrop_a_lo = 0x29;
+		ptiming->range_config__timeout_macrop_b_hi = 0x00;
+		ptiming->range_config__timeout_macrop_b_lo = 0x22;
+		pgeneral->cal_config__vcsel_start = 0x09;
+		pgeneral->phasecal_config__timeout_macrop = 0xF5;
+		pdynamic->sd_config__woi_sd0 = 0x09;
+		pdynamic->sd_config__woi_sd1 = 0x0B;
+		pdynamic->sd_config__initial_phase_sd0 = ptuning_parms->tp_init_phase_rtn_hist_long;
+		pdynamic->sd_config__initial_phase_sd1 = ptuning_parms->tp_init_phase_ref_hist_long;
+		phistpostprocess->valid_phase_low = 0x08;
+		phistpostprocess->valid_phase_high = 0x88;
+		pdynamic->system__sequence_config = VL53LX_SEQUENCE_VHV_EN | VL53LX_SEQUENCE_PHASECAL_EN | VL53LX_SEQUENCE_DSS1_EN | VL53LX_SEQUENCE_DSS2_EN | VL53LX_SEQUENCE_RANGE_EN;
+		psystem->system__mode_start = VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | VL53LX_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 = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	if (pdev->dbg_results.result__osc_calibrate_val == 0)
+		status = VL53LX_ERROR_DIVISION_BY_ZERO;
+
+	if (status == VL53LX_ERROR_NONE) {
+		pdev->inter_measurement_period_ms = inter_measurement_period_ms;
+		pdev->tim_cfg.system__intermeasurement_period = inter_measurement_period_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 = VL53LX_ERROR_NONE;
+
+	status = VL53LX_preset_mode_histogram_ranging(phistpostprocess, pstatic, phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cfg);
+
+	if (status == 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, ptiming, pdynamic);
+
+		ptiming->range_config__vcsel_period_a = 0x05;
+		ptiming->range_config__vcsel_period_b = 0x07;
+
+		ptiming->mm_config__timeout_macrop_a_hi = 0x00;
+		ptiming->mm_config__timeout_macrop_a_lo = 0x36;
+		ptiming->mm_config__timeout_macrop_b_hi = 0x00;
+		ptiming->mm_config__timeout_macrop_b_lo = 0x28;
+
+		ptiming->range_config__timeout_macrop_a_hi = 0x00;
+		ptiming->range_config__timeout_macrop_a_lo = 0x44;
+		ptiming->range_config__timeout_macrop_b_hi = 0x00;
+		ptiming->range_config__timeout_macrop_b_lo = 0x33;
+
+		pgeneral->cal_config__vcsel_start = 0x05;
+
+		pgeneral->phasecal_config__timeout_macrop = 0xF5;
+
+		pdynamic->sd_config__woi_sd0 = 0x05;
+		pdynamic->sd_config__woi_sd1 = 0x07;
+		pdynamic->sd_config__initial_phase_sd0            = ptuning_parms->tp_init_phase_rtn_hist_med;
+		pdynamic->sd_config__initial_phase_sd1            = ptuning_parms->tp_init_phase_ref_hist_med;
+
+		phistpostprocess->valid_phase_low = 0x08;
+		phistpostprocess->valid_phase_high = 0x48;
+
+		pdynamic->system__sequence_config = VL53LX_SEQUENCE_VHV_EN | VL53LX_SEQUENCE_PHASECAL_EN | VL53LX_SEQUENCE_DSS1_EN | VL53LX_SEQUENCE_DSS2_EN | VL53LX_SEQUENCE_RANGE_EN;
+
+		psystem->system__mode_start = VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | VL53LX_DEVICEREADOUTMODE_DUAL_SD | VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
+	}
+	return status;
+}
+
+
+VL53LX_Error VL53LX_set_preset_mode(VL53LX_DEV Dev, VL53LX_DevicePresetModes 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 = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+
+	VL53LX_hist_post_process_config_t *phistpostprocess = &(pdev->histpostprocess);
+
+	VL53LX_static_config_t        *pstatic       = &(pdev->stat_cfg);
+	VL53LX_histogram_config_t     *phistogram    = &(pdev->hist_cfg);
+	VL53LX_general_config_t       *pgeneral      = &(pdev->gen_cfg);
+	VL53LX_timing_config_t        *ptiming       = &(pdev->tim_cfg);
+	VL53LX_dynamic_config_t       *pdynamic      = &(pdev->dyn_cfg);
+	VL53LX_system_control_t       *psystem       = &(pdev->sys_ctrl);
+	VL53LX_zone_config_t          *pzone_cfg     = &(pdev->zone_cfg);
+	VL53LX_tuning_parm_storage_t  *ptuning_parms = &(pdev->tuning_parms);
+
+	pdev->preset_mode                 = device_preset_mode;
+	pdev->mm_config_timeout_us        = mm_config_timeout_us;
+	pdev->range_config_timeout_us     = range_config_timeout_us;
+	pdev->inter_measurement_period_ms = 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 = VL53LX_preset_mode_histogram_long_range(phistpostprocess, pstatic, phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cfg);
+		break;
+	case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE:
+		status = VL53LX_preset_mode_histogram_medium_range(phistpostprocess, pstatic, phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cfg);
+		break;
+	case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE:
+		status = VL53LX_preset_mode_histogram_short_range(phistpostprocess, pstatic, phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cfg);
+		break;
+	default:
+		status = VL53LX_ERROR_INVALID_PARAMS;
+		break;
+	}
+	if (status == VL53LX_ERROR_NONE) {
+		pstatic->dss_config__target_total_rate_mcps = dss_config__target_total_rate_mcps;
+		pdev->dss_config__target_total_rate_mcps = dss_config__target_total_rate_mcps;
+	}
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_set_timeouts_us(Dev, phasecal_config_timeout_us, mm_config_timeout_us, range_config_timeout_us);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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 = VL53LX_ERROR_NONE;
+	VL53LX_DevicePresetModes   device_preset_mode;
+	uint8_t measurement_mode;
+	uint16_t dss_config__target_total_rate_mcps = 0;
+	uint32_t phasecal_config_timeout_us = 0;
+	uint32_t mm_config_timeout_us = 0;
+	uint32_t lld_range_config_timeout_us = 0;
+
+	measurement_mode  = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
+
+	Status = ComputeDevicePresetMode(DistanceMode, &device_preset_mode);
+
+	if (Status == VL53LX_ERROR_NONE)
+		Status =  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 == VL53LX_ERROR_NONE)
+		Status = VL53LX_set_preset_mode(Dev, device_preset_mode, dss_config__target_total_rate_mcps, phasecal_config_timeout_us, mm_config_timeout_us, lld_range_config_timeout_us, inter_measurement_period_ms);
+
+	if (Status == VL53LX_ERROR_NONE)
+		VL53LXDevDataSet(Dev, LLData.measurement_mode, measurement_mode);
+
+	return Status;
+}
+
+VL53LX_Error VL53LX_SetDistanceMode(VL53LX_DEV Dev, VL53LX_DistanceModes DistanceMode)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	uint32_t inter_measurement_period_ms;
+	uint32_t TimingBudget = 0;
+	uint32_t MmTimeoutUs = 0;
+	uint32_t PhaseCalTimeoutUs = 0;
+
+	if ((DistanceMode != VL53LX_DISTANCEMODE_SHORT) && (DistanceMode != VL53LX_DISTANCEMODE_MEDIUM) && (DistanceMode != VL53LX_DISTANCEMODE_LONG))
+		return VL53LX_ERROR_INVALID_PARAMS;
+
+	if (IsL4(Dev) && (DistanceMode == VL53LX_DISTANCEMODE_SHORT))
+		return VL53LX_ERROR_INVALID_PARAMS;
+
+	inter_measurement_period_ms = VL53LXDevDataGet(Dev, LLData.inter_measurement_period_ms);
+
+	if (Status == VL53LX_ERROR_NONE)
+		Status = VL53LX_get_timeouts_us(Dev, &PhaseCalTimeoutUs, &MmTimeoutUs, &TimingBudget);
+
+	if (Status == VL53LX_ERROR_NONE)
+		Status = SetPresetModeL3CX(Dev, DistanceMode, inter_measurement_period_ms);
+
+	if (Status == VL53LX_ERROR_NONE) {
+		VL53LXDevDataSet(Dev, CurrentParameters.DistanceMode, DistanceMode);
+	}
+
+	if (Status == VL53LX_ERROR_NONE) {
+		Status = VL53LX_set_timeouts_us(Dev, PhaseCalTimeoutUs, MmTimeoutUs, TimingBudget);
+
+		if (Status == VL53LX_ERROR_NONE)
+			VL53LXDevDataSet(Dev, LLData.range_config_timeout_us, TimingBudget);
+	}
+	return Status;
+}
+
+VL53LX_Error VL53LX_set_offset_correction_mode(VL53LX_DEV Dev, VL53LX_OffsetCorrectionMode offset_cor_mode)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->offset_correction_mode = offset_cor_mode;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_SetOffsetCorrectionMode(VL53LX_DEV Dev, VL53LX_OffsetCorrectionModes OffsetCorrectionMode)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	VL53LX_OffsetCorrectionMode offset_cor_mode;
+
+	if (OffsetCorrectionMode == VL53LX_OFFSETCORRECTIONMODE_PERVCSEL)
+		offset_cor_mode = VL53LX_OFFSETCORRECTIONMODE__PER_VCSEL_OFFSETS;
+	else {
+		offset_cor_mode = VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS;
+		if (OffsetCorrectionMode != VL53LX_OFFSETCORRECTIONMODE_STANDARD)
+			Status = VL53LX_ERROR_INVALID_PARAMS;
+	}
+
+	if (Status == VL53LX_ERROR_NONE)
+		Status = VL53LX_set_offset_correction_mode(Dev, offset_cor_mode);
+
+	return Status;
+}
+
+VL53LX_Error VL53LX_dynamic_xtalk_correction_disable(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->smudge_correct_config.smudge_corr_enabled = 0;
+	return status;
+}
+
+VL53LX_Error VL53LX_dynamic_xtalk_correction_apply_disable(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->smudge_correct_config.smudge_corr_apply_enabled = 0;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_dynamic_xtalk_correction_single_apply_disable(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->smudge_correct_config.smudge_corr_single_apply = 0;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_dynamic_xtalk_correction_enable(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->smudge_correct_config.smudge_corr_enabled = 1;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_dynamic_xtalk_correction_apply_enable(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->smudge_correct_config.smudge_corr_apply_enabled = 1;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_dynamic_xtalk_correction_single_apply_enable(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->smudge_correct_config.smudge_corr_single_apply = 1;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_SmudgeCorrectionEnable(VL53LX_DEV Dev, VL53LX_SmudgeCorrectionModes Mode)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	VL53LX_Error s1 = VL53LX_ERROR_NONE;
+	VL53LX_Error s2 = VL53LX_ERROR_NONE;
+	VL53LX_Error s3 = VL53LX_ERROR_NONE;
+
+	switch (Mode) {
+	case VL53LX_SMUDGE_CORRECTION_NONE:
+		s1 = VL53LX_dynamic_xtalk_correction_disable(Dev);
+		s2 = VL53LX_dynamic_xtalk_correction_apply_disable(Dev);
+		s3 = VL53LX_dynamic_xtalk_correction_single_apply_disable(Dev);
+		break;
+	case VL53LX_SMUDGE_CORRECTION_CONTINUOUS:
+		s1 = VL53LX_dynamic_xtalk_correction_enable(Dev);
+		s2 = VL53LX_dynamic_xtalk_correction_apply_enable(Dev);
+		s3 = VL53LX_dynamic_xtalk_correction_single_apply_disable(Dev);
+		break;
+	case VL53LX_SMUDGE_CORRECTION_SINGLE:
+		s1 = VL53LX_dynamic_xtalk_correction_enable(Dev);
+		s2 = VL53LX_dynamic_xtalk_correction_apply_enable(Dev);
+		s3 = VL53LX_dynamic_xtalk_correction_single_apply_enable(Dev);
+		break;
+	case VL53LX_SMUDGE_CORRECTION_DEBUG:
+		s1 = VL53LX_dynamic_xtalk_correction_enable(Dev);
+		s2 = VL53LX_dynamic_xtalk_correction_apply_disable(Dev);
+		s3 = VL53LX_dynamic_xtalk_correction_single_apply_disable(Dev);
+		break;
+	default:
+		Status = VL53LX_ERROR_INVALID_PARAMS;
+		break;
+	}
+
+	if (Status == VL53LX_ERROR_NONE) {
+		Status = s1;
+		if (Status == VL53LX_ERROR_NONE)
+			Status = s2;
+		if (Status == VL53LX_ERROR_NONE)
+			Status = s3;
+	}
+	return Status;
+}
+
+static VL53LX_Error CheckValidRectRoi(VL53LX_UserRoi_t ROI)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+
+	if ((ROI.TopLeftX > 15) || (ROI.TopLeftY > 15) || (ROI.BotRightX > 15) || (ROI.BotRightY > 15))
+		Status = VL53LX_ERROR_INVALID_PARAMS;
+	if ((ROI.TopLeftX > ROI.BotRightX) || (ROI.TopLeftY < ROI.BotRightY))
+		Status = VL53LX_ERROR_INVALID_PARAMS;
+
+	return Status;
+}
+
+VL53LX_Error VL53LX_init_zone_config_histogram_bins(VL53LX_zone_config_t *pdata)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	uint8_t i;
+
+	for (i = 0; i < pdata->max_zones; i++)
+		pdata->bin_config[i] = VL53LX_ZONECONFIG_BINCONFIG__LOWAMB;
+
+	return status;
+}
+
+
+VL53LX_Error VL53LX_set_zone_config(VL53LX_DEV Dev, VL53LX_zone_config_t *pzone_cfg)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	memcpy(&(pdev->zone_cfg.user_zones), &(pzone_cfg->user_zones), sizeof(pdev->zone_cfg.user_zones));
+
+	pdev->zone_cfg.max_zones    = pzone_cfg->max_zones;
+	pdev->zone_cfg.active_zones = pzone_cfg->active_zones;
+
+	status = VL53LX_init_zone_config_histogram_bins(&pdev->zone_cfg);
+
+	if (pzone_cfg->active_zones == 0)
+		pdev->gen_cfg.global_config__stream_divider = 0;
+	else if (pzone_cfg->active_zones < VL53LX_MAX_USER_ZONES)
+		pdev->gen_cfg.global_config__stream_divider = pzone_cfg->active_zones + 1;
+	else
+		pdev->gen_cfg.global_config__stream_divider = VL53LX_MAX_USER_ZONES + 1;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_SetUserROI(VL53LX_DEV Dev, VL53LX_UserRoi_t *pRoi)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	VL53LX_zone_config_t  zone_cfg;
+	uint8_t x_centre, y_centre, width, height;
+
+	Status = CheckValidRectRoi(*pRoi);
+	if (Status != VL53LX_ERROR_NONE)
+		return VL53LX_ERROR_INVALID_PARAMS;
+
+	x_centre = (pRoi->BotRightX + pRoi->TopLeftX  + 1) / 2;
+	y_centre = (pRoi->TopLeftY  + pRoi->BotRightY + 1) / 2;
+	width =    (pRoi->BotRightX - pRoi->TopLeftX);
+	height =   (pRoi->TopLeftY  - pRoi->BotRightY);
+	zone_cfg.max_zones = 1;
+	zone_cfg.active_zones = 0;
+	zone_cfg.user_zones[0].x_centre = x_centre;
+	zone_cfg.user_zones[0].y_centre = y_centre;
+	zone_cfg.user_zones[0].width = width;
+	zone_cfg.user_zones[0].height = height;
+	if ((width < 3) || (height < 3))
+		Status = VL53LX_ERROR_INVALID_PARAMS;
+	else
+		Status =  VL53LX_set_zone_config(Dev, &zone_cfg);
+
+	return Status;
+}
+
+static int stmvl53lx_sendparams(struct stmvl53lx_data *data)
+{
+	int rc = 0;
+
+	rc = VL53LX_SetXTalkCompensationEnable(&data->stdev, data->crosstalk_enable);
+	if (rc) {
+		vl53lx_errmsg("VL53LX_SetXTalkCompensationEnable %d fail %d", data->crosstalk_enable, rc);
+		rc = store_last_error(data, rc);
+		goto done;
+	}
+	vl53lx_dbgmsg("Xtalk enable @%d\n", data->crosstalk_enable);
+
+	rc = VL53LX_SetDistanceMode(&data->stdev, data->distance_mode);
+	if (rc) {
+		vl53lx_errmsg("VL53LX_SetDistanceMode %d fail %d", data->distance_mode, rc);
+		rc = store_last_error(data, rc);
+		goto done;
+	}
+	vl53lx_dbgmsg("distance mode @%d\n", data->distance_mode);
+
+	rc = VL53LX_SetMeasurementTimingBudgetMicroSeconds(&data->stdev, data->timing_budget);
+	if (rc) {
+		vl53lx_errmsg("SetTimingBudget %d fail %d", data->timing_budget, rc);
+		rc = store_last_error(data, rc);
+		goto done;
+	}
+	vl53lx_dbgmsg("timing budget @%d\n", data->timing_budget);
+
+	rc = VL53LX_SetOffsetCorrectionMode(&data->stdev, data->offset_correction_mode);
+	if (rc) {
+		vl53lx_errmsg("offset correction mode %d fail %d", data->offset_correction_mode, rc);
+		rc = store_last_error(data, rc);
+		goto done;
+	}
+	vl53lx_dbgmsg("offset correction mode @%d\n", data->offset_correction_mode);
+
+	rc =  VL53LX_SmudgeCorrectionEnable(&data->stdev, data->smudge_correction_mode);
+	if (rc) {
+		vl53lx_errmsg("smudge correction mode %d fail %d", data->smudge_correction_mode, rc);
+		rc = store_last_error(data, rc);
+		goto done;
+	}
+	vl53lx_dbgmsg("smudge correction mode @%d\n", data->smudge_correction_mode);
+
+	rc = VL53LX_SetUserROI(&data->stdev, &data->roi_cfg);
+	if (rc) {
+		vl53lx_errmsg("VL53LX_SetUserROI fail %d\n", rc);
+		rc = store_last_error(data, rc);
+		goto done;
+	}
+	vl53lx_dbgmsg("ROI set TopLeft(%d %d) BottomRight(%d %d)\n", data->roi_cfg.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 = 0; i < VL53LX_MAX_RANGE_RESULTS; i++)
+		pdata->RangeData[i].RangeStatus = VL53LX_RANGESTATUS_NONE;
+}
+
+VL53LX_Error VL53LX_enable_powerforce(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	status = VL53LX_set_powerforce_register(Dev, 0x01);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_get_tuning_parm(VL53LX_DEV Dev, VL53LX_TuningParms tuning_parm_key, int32_t *ptuning_parm_value)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
+	VL53LX_xtalkextract_config_t *pXC = &(pdev->xtalk_extract_cfg);
+
+	switch (tuning_parm_key) {
+	case VL53LX_TUNINGPARM_VERSION:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_tuning_parm_version;
+		break;
+	case VL53LX_TUNINGPARM_KEY_TABLE_VERSION:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_tuning_parm_key_table_version;
+		break;
+	case VL53LX_TUNINGPARM_LLD_VERSION:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_tuning_parm_lld_version;
+		break;
+	case VL53LX_TUNINGPARM_HIST_ALGO_SELECT:
+		*ptuning_parm_value = (int32_t)pHP->hist_algo_select;
+		break;
+	case VL53LX_TUNINGPARM_HIST_TARGET_ORDER:
+		*ptuning_parm_value = (int32_t)pHP->hist_target_order;
+		break;
+	case VL53LX_TUNINGPARM_HIST_FILTER_WOI_0:
+		*ptuning_parm_value = (int32_t)pHP->filter_woi0;
+		break;
+	case VL53LX_TUNINGPARM_HIST_FILTER_WOI_1:
+		*ptuning_parm_value = (int32_t)pHP->filter_woi1;
+		break;
+	case VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD:
+		*ptuning_parm_value = (int32_t)pHP->hist_amb_est_method;
+		break;
+	case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0:
+		*ptuning_parm_value = (int32_t)pHP->ambient_thresh_sigma0;
+		break;
+	case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1:
+		*ptuning_parm_value = (int32_t)pHP->ambient_thresh_sigma1;
+		break;
+	case VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS:
+		*ptuning_parm_value = (int32_t)pHP->min_ambient_thresh_events;
+		break;
+	case VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER:
+		*ptuning_parm_value = (int32_t)pHP->ambient_thresh_events_scaler;
+		break;
+	case VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD:
+		*ptuning_parm_value = (int32_t)pHP->noise_threshold;
+		break;
+	case VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT:
+		*ptuning_parm_value = (int32_t)pHP->signal_total_events_limit;
+		break;
+	case VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM:
+		*ptuning_parm_value = (int32_t)pHP->sigma_estimator__sigma_ref_mm;
+		break;
+	case VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM:
+		*ptuning_parm_value = (int32_t)pHP->sigma_thresh;
+		break;
+	case VL53LX_TUNINGPARM_HIST_GAIN_FACTOR:
+		*ptuning_parm_value = (int32_t)pdev->gain_cal.histogram_ranging_gain_factor;
+		break;
+	case VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE:
+		*ptuning_parm_value = (int32_t)pHP->algo__consistency_check__phase_tolerance;
+		break;
+	case VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM:
+		*ptuning_parm_value = (int32_t)pHP->algo__consistency_check__min_max_tolerance;
+		break;
+	case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA:
+		*ptuning_parm_value = (int32_t)pHP->algo__consistency_check__event_sigma;
+		break;
+	case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT:
+		*ptuning_parm_value = (int32_t)pHP->algo__consistency_check__event_min_spad_count;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hist_long;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hist_med;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_rtn_hist_short;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_ref_hist_long;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_ref_hist_med;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_ref_hist_short;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM:
+		*ptuning_parm_value = (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 = (int32_t)(pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm);
+		break;
+	case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM:
+		*ptuning_parm_value = (int32_t)pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE:
+		*ptuning_parm_value = (int32_t)pHP->algo__crosstalk_detect_min_max_tolerance;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS:
+		*ptuning_parm_value = (int32_t)(pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_rate_kcps);
+		break;
+	case VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA:
+		*ptuning_parm_value = (int32_t)pHP->algo__crosstalk_detect_event_sigma;
+		break;
+	case VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS:
+		*ptuning_parm_value = (int32_t)pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps;
+		break;
+	case VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_consistency_lite_phase_tolerance;
+		break;
+	case VL53LX_TUNINGPARM_PHASECAL_TARGET:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_phasecal_target;
+		break;
+	case VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_cal_repeat_rate;
+		break;
+	case VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR:
+		*ptuning_parm_value = (int32_t)pdev->gain_cal.standard_ranging_gain_factor;
+		break;
+	case VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_lite_min_clip;
+		break;
+	case VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_lite_long_sigma_thresh_mm;
+		break;
+	case VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_lite_med_sigma_thresh_mm;
+		break;
+	case VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM:
+		*ptuning_parm_value = (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 = (int32_t)(pdev->tuning_parms.tp_lite_long_min_count_rate_rtn_mcps);
+		break;
+	case VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_lite_med_min_count_rate_rtn_mcps;
+		break;
+	case VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS:
+		*ptuning_parm_value = (int32_t)(pdev->tuning_parms.tp_lite_short_min_count_rate_rtn_mcps);
+		break;
+	case VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_lite_sigma_est_pulse_width_ns;
+		break;
+	case VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_lite_sigma_est_amb_width_ns;
+		break;
+	case VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_lite_sigma_ref_mm;
+		break;
+	case VL53LX_TUNINGPARM_LITE_RIT_MULT:
+		*ptuning_parm_value = (int32_t)pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult;
+		break;
+	case VL53LX_TUNINGPARM_LITE_SEED_CONFIG:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_lite_seed_cfg;
+		break;
+	case VL53LX_TUNINGPARM_LITE_QUANTIFIER:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_lite_quantifier;
+		break;
+	case VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_lite_first_order_select;
+		break;
+	case VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS:
+		*ptuning_parm_value = (int32_t)pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_rtn_lite_long;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_rtn_lite_med;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_rtn_lite_short;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_ref_lite_long;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_ref_lite_med;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_init_phase_ref_lite_short;
+		break;
+	case VL53LX_TUNINGPARM_TIMED_SEED_CONFIG:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_timed_seed_cfg;
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA:
+		*ptuning_parm_value = (int32_t)pdev->dmax_cfg.signal_thresh_sigma;
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0:
+		*ptuning_parm_value = (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[0];
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1:
+		*ptuning_parm_value = (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[1];
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2:
+		*ptuning_parm_value = (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[2];
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3:
+		*ptuning_parm_value = (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[3];
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4:
+		*ptuning_parm_value = (int32_t)pdev->dmax_cfg.target_reflectance_for_dmax_calc[4];
+		break;
+	case VL53LX_TUNINGPARM_VHV_LOOPBOUND:
+		*ptuning_parm_value = (int32_t)pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE:
+		*ptuning_parm_value = (int32_t)pdev->refspadchar.device_test_mode;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD:
+		*ptuning_parm_value = (int32_t)pdev->refspadchar.VL53LX_p_005;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->refspadchar.timeout_us;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS:
+		*ptuning_parm_value = (int32_t)pdev->refspadchar.target_count_rate_mcps;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS:
+		*ptuning_parm_value = (int32_t)pdev->refspadchar.min_count_rate_limit_mcps;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS:
+		*ptuning_parm_value = (int32_t)pdev->refspadchar.max_count_rate_limit_mcps;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES:
+		*ptuning_parm_value = (int32_t)pXC->num_of_samples;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM:
+		*ptuning_parm_value = (int32_t)pXC->algo__crosstalk_extract_min_valid_range_mm;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM:
+		*ptuning_parm_value = (int32_t)pXC->algo__crosstalk_extract_max_valid_range_mm;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS:
+		*ptuning_parm_value = (int32_t)pXC->dss_config__target_total_rate_mcps;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pXC->phasecal_config_timeout_us;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS:
+		*ptuning_parm_value = (int32_t)pXC->algo__crosstalk_extract_max_valid_rate_kcps;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM:
+		*ptuning_parm_value = (int32_t)pXC->algo__crosstalk_extract_max_sigma_mm;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pXC->mm_config_timeout_us;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pXC->range_config_timeout_us;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS:
+		*ptuning_parm_value = (int32_t)pdev->offsetcal_cfg.dss_config__target_total_rate_mcps;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->offsetcal_cfg.phasecal_config_timeout_us;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->offsetcal_cfg.mm_config_timeout_us;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->offsetcal_cfg.range_config_timeout_us;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES:
+		*ptuning_parm_value = (int32_t)pdev->offsetcal_cfg.pre_num_of_samples;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES:
+		*ptuning_parm_value = (int32_t)pdev->offsetcal_cfg.mm1_num_of_samples;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES:
+		*ptuning_parm_value = (int32_t)pdev->offsetcal_cfg.mm2_num_of_samples;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS:
+		*ptuning_parm_value = (int32_t)pdev->zonecal_cfg.dss_config__target_total_rate_mcps;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->zonecal_cfg.phasecal_config_timeout_us;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->zonecal_cfg.mm_config_timeout_us;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES:
+		*ptuning_parm_value = (int32_t)pdev->zonecal_cfg.phasecal_num_of_samples;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->zonecal_cfg.range_config_timeout_us;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES:
+		*ptuning_parm_value = (int32_t)pdev->zonecal_cfg.zone_num_of_samples;
+		break;
+	case VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD:
+		*ptuning_parm_value = (int32_t)pdev->ssc_cfg.VL53LX_p_005;
+		break;
+	case VL53LX_TUNINGPARM_SPADMAP_VCSEL_START:
+		*ptuning_parm_value = (int32_t)pdev->ssc_cfg.vcsel_start;
+		break;
+	case VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS:
+		*ptuning_parm_value = (int32_t)pdev->ssc_cfg.rate_limit_mcps;
+		break;
+	case VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_dss_target_lite_mcps;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_dss_target_histo_mcps;
+		break;
+	case VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
+		*ptuning_parm_value = (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 = (int32_t)pdev->tuning_parms.tp_dss_target_timed_mcps;
+		break;
+	case VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_phasecal_timeout_lite_us;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_phasecal_timeout_hist_long_us;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_phasecal_timeout_hist_med_us;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_phasecal_timeout_hist_short_us;
+		break;
+	case VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_phasecal_timeout_mz_long_us;
+		break;
+	case VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_phasecal_timeout_mz_med_us;
+		break;
+	case VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_phasecal_timeout_mz_short_us;
+		break;
+	case VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_phasecal_timeout_timed_us;
+		break;
+	case VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_mm_timeout_lite_us;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_mm_timeout_histo_us;
+		break;
+	case VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_mm_timeout_mz_us;
+		break;
+	case VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_mm_timeout_timed_us;
+		break;
+	case VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_range_timeout_lite_us;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_range_timeout_histo_us;
+		break;
+	case VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_range_timeout_mz_us;
+		break;
+	case VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_range_timeout_timed_us;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.smudge_margin;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.noise_margin;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.user_xtalk_offset_limit;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.user_xtalk_offset_limit_hi;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.sample_limit;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.single_xtalk_delta;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.averaged_xtalk_delta;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.smudge_corr_clip_limit;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_SCALER_CALC_METHOD:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.scaler_calc_method;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.x_gradient_scaler;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.y_gradient_scaler;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.user_scaler_set;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.smudge_corr_single_apply;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD:
+		*ptuning_parm_value = (int32_t)(pdev->smudge_correct_config.smudge_corr_ambient_threshold);
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.nodetect_ambient_threshold;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.nodetect_sample_limit;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.nodetect_xtalk_offset;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM:
+		*ptuning_parm_value = (int32_t)pdev->smudge_correct_config.nodetect_min_range_mm;
+		break;
+	case VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND:
+		*ptuning_parm_value = (int32_t)pdev->low_power_auto_data.vhv_loop_bound;
+		break;
+	case VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_mm_timeout_lpa_us;
+		break;
+	case VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_range_timeout_lpa_us;
+		break;
+	case VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS:
+		*ptuning_parm_value = (int32_t)pdev->tuning_parms.tp_dss_target_very_short_mcps;
+		break;
+	case VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER:
+		*ptuning_parm_value = (int32_t) pdev->tuning_parms.tp_phasecal_patch_power;
+		break;
+	case VL53LX_TUNINGPARM_HIST_MERGE:
+		*ptuning_parm_value = (int32_t) pdev->tuning_parms.tp_hist_merge;
+		break;
+	case VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD:
+		*ptuning_parm_value = (int32_t) pdev->tuning_parms.tp_reset_merge_threshold;
+		break;
+	case VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE:
+		*ptuning_parm_value = (int32_t) pdev->tuning_parms.tp_hist_merge_max_size;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR:
+		*ptuning_parm_value = pdev->smudge_correct_config.max_smudge_factor;
+		break;
+	case VL53LX_TUNINGPARM_UWR_ENABLE:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_enable;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MIN:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_z_1_min;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MAX:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_z_1_max;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MIN:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_z_2_min;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MAX:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_z_2_max;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MIN:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_z_3_min;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MAX:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_z_3_max;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MIN:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_z_4_min;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MAX:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_z_4_max;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MIN:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_z_5_min;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MAX:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_z_5_max;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEA:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_corr_z_1_rangea;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEB:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_corr_z_1_rangeb;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEA:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_corr_z_2_rangea;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEB:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_corr_z_2_rangeb;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEA:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_corr_z_3_rangea;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEB:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_corr_z_3_rangeb;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEA:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_corr_z_4_rangea;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEB:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_corr_z_4_rangeb;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEA:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_corr_z_5_rangea;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEB:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_med_corr_z_5_rangeb;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MIN:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_z_1_min;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MAX:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_z_1_max;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MIN:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_z_2_min;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MAX:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_z_2_max;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MIN:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_z_3_min;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MAX:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_z_3_max;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MIN:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_z_4_min;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MAX:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_z_4_max;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MIN:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_z_5_min;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MAX:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_z_5_max;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEA:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_corr_z_1_rangea;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEB:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_corr_z_1_rangeb;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEA:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_corr_z_2_rangea;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEB:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_corr_z_2_rangeb;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEA:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_corr_z_3_rangea;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEB:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_corr_z_3_rangeb;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEA:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_corr_z_4_rangea;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEB:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_corr_z_4_rangeb;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEA:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_corr_z_5_rangea;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEB:
+		*ptuning_parm_value = pdev->tuning_parms.tp_uwr_lng_corr_z_5_rangeb;
+		break;
+	default:
+		*ptuning_parm_value = 0x7FFFFFFF;
+		status = VL53LX_ERROR_INVALID_PARAMS;
+		break;
+
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_load_patch(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	int32_t patch_tuning = 0;
+	uint8_t comms_buffer[256];
+	uint32_t patch_power;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, 0x00);
+
+	if (status == VL53LX_ERROR_NONE)
+		VL53LX_enable_powerforce(Dev);
+
+	VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER, &patch_tuning);
+
+	switch (patch_tuning) {
+	case 0:
+		patch_power = 0x00;
+		break;
+	case 1:
+		patch_power = 0x10;
+		break;
+	case 2:
+		patch_power = 0x20;
+		break;
+	case 3:
+		patch_power = 0x40;
+		break;
+	default:
+		patch_power = 0x00;
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+		comms_buffer[0] = 0x29;
+		comms_buffer[1] = 0xC9;
+		comms_buffer[2] = 0x0E;
+		comms_buffer[3] = 0x40;
+		comms_buffer[4] = 0x28;
+		comms_buffer[5] = patch_power;
+		status = VL53LX_WriteMulti(Dev, VL53LX_PATCH__OFFSET_0, comms_buffer, 6);
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+		comms_buffer[0] = 0x03;
+		comms_buffer[1] = 0x6D;
+		comms_buffer[2] = 0x03;
+		comms_buffer[3] = 0x6F;
+		comms_buffer[4] = 0x07;
+		comms_buffer[5] = 0x29;
+		status = VL53LX_WriteMulti(Dev, VL53LX_PATCH__ADDRESS_0, comms_buffer, 6);
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+		comms_buffer[0] = 0x00;
+		comms_buffer[1] = 0x07;
+		status = VL53LX_WriteMulti(Dev, VL53LX_PATCH__JMP_ENABLES, comms_buffer, 2);
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+		comms_buffer[0] = 0x00;
+		comms_buffer[1] = 0x07;
+		status = VL53LX_WriteMulti(Dev, VL53LX_PATCH__DATA_ENABLES, comms_buffer, 2);
+	}
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_PATCH__CTRL, 0x01);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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 = 128 + (col << 3) + (15-row);
+	else
+		*pspad_number = ((15-col) << 3) + row;
+}
+
+void VL53LX_encode_zone_size(uint8_t width, uint8_t height, uint8_t *pencoded_xy_size)
+{
+	*pencoded_xy_size = (height << 4) + width;
+}
+
+VL53LX_Error VL53LX_set_user_zone(VL53LX_DEV Dev, VL53LX_user_zone_t *puser_zone)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = 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->dyn_cfg.roi_config__user_roi_requested_global_xy_size));
+
+	return status;
+}
+
+VL53LX_Error VL53LX_set_zone_dss_config(VL53LX_DEV Dev, VL53LX_zone_private_dyn_cfg_t *pzone_dyn_cfg)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state);
+
+	if (pstate->cfg_device_state == VL53LX_DEVICESTATE_RANGING_DSS_MANUAL) {
+		pdev->gen_cfg.dss_config__roi_mode_control = VL53LX_DSS_CONTROL__MODE_EFFSPADS;
+		pdev->gen_cfg.dss_config__manual_effective_spads_select = pzone_dyn_cfg->dss_requested_effective_spad_count;
+	} else {
+		pdev->gen_cfg.dss_config__roi_mode_control = VL53LX_DSS_CONTROL__MODE_TARGET_RATE;
+	}
+
+	return status;
+}
+
+VL53LX_Error VL53LX_save_cfg_data(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+
+	VL53LX_zone_private_dyn_cfg_t *pzone_dyn_cfg;
+	VL53LX_dynamic_config_t       *pdynamic = &(pdev->dyn_cfg);
+
+	pzone_dyn_cfg = &(pres->zone_dyn_cfgs.VL53LX_p_003[pdev->ll_state.cfg_zone_id]);
+	pzone_dyn_cfg->expected_stream_count = pdev->ll_state.cfg_stream_count;
+	pzone_dyn_cfg->expected_gph_id = pdev->ll_state.cfg_gph_id;
+	pzone_dyn_cfg->roi_config__user_roi_centre_spad = pdynamic->roi_config__user_roi_centre_spad;
+	pzone_dyn_cfg->roi_config__user_roi_requested_global_xy_size = pdynamic->roi_config__user_roi_requested_global_xy_size;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_i2c_encode_static_nvm_managed(VL53LX_static_nvm_managed_t *pdata, uint16_t buf_size, uint8_t *pbuffer)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (buf_size < VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES)
+		return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
+
+	*(pbuffer +   0) = pdata->i2c_slave__device_address & 0x7F;
+	*(pbuffer +   1) = pdata->ana_config__vhv_ref_sel_vddpix & 0xF;
+	*(pbuffer +   2) = pdata->ana_config__vhv_ref_sel_vquench & 0x7F;
+	*(pbuffer +   3) = pdata->ana_config__reg_avdd1v2_sel & 0x3;
+	*(pbuffer +   4) = pdata->ana_config__fast_osc__trim & 0x7F;
+	VL53LX_i2c_encode_uint16_t(pdata->osc_measured__fast_osc__frequency, 2, pbuffer +   5);
+	*(pbuffer +   7) = pdata->vhv_config__timeout_macrop_loop_bound;
+	*(pbuffer +   8) = pdata->vhv_config__count_thresh;
+	*(pbuffer +   9) = pdata->vhv_config__offset & 0x3F;
+	*(pbuffer +  10) = 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 = 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 =
+		(*(pbuffer +   0)) & 0x7F;
+	pdata->ana_config__vhv_ref_sel_vddpix =
+		(*(pbuffer +   1)) & 0xF;
+	pdata->ana_config__vhv_ref_sel_vquench =
+		(*(pbuffer +   2)) & 0x7F;
+	pdata->ana_config__reg_avdd1v2_sel =
+		(*(pbuffer +   3)) & 0x3;
+	pdata->ana_config__fast_osc__trim =
+		(*(pbuffer +   4)) & 0x7F;
+	pdata->osc_measured__fast_osc__frequency =
+		(VL53LX_i2c_decode_uint16_t(2, pbuffer +   5));
+	pdata->vhv_config__timeout_macrop_loop_bound =
+		(*(pbuffer +   7));
+	pdata->vhv_config__count_thresh =
+		(*(pbuffer +   8));
+	pdata->vhv_config__offset =
+		(*(pbuffer +   9)) & 0x3F;
+	pdata->vhv_config__init =
+		(*(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 = 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) = pdata->debug__ctrl & 0x1;
+	*(pbuffer +   3) = pdata->test_mode__ctrl & 0xF;
+	*(pbuffer +   4) = pdata->clk_gating__ctrl & 0xF;
+	*(pbuffer +   5) = pdata->nvm_bist__ctrl & 0x1F;
+	*(pbuffer +   6) = pdata->nvm_bist__num_nvm_words & 0x7F;
+	*(pbuffer +   7) = pdata->nvm_bist__start_address & 0x7F;
+	*(pbuffer +   8) = pdata->host_if__status & 0x1;
+	*(pbuffer +   9) = pdata->pad_i2c_hv__config;
+	*(pbuffer +  10) = pdata->pad_i2c_hv__extsup_config & 0x1;
+	*(pbuffer +  11) = pdata->gpio_hv_pad__ctrl & 0x3;
+	*(pbuffer +  12) = pdata->gpio_hv_mux__ctrl & 0x1F;
+	*(pbuffer +  13) = pdata->gpio__tio_hv_status & 0x3;
+	*(pbuffer +  14) = pdata->gpio__fio_hv_status & 0x3;
+	*(pbuffer +  15) = pdata->ana_config__spad_sel_pswidth & 0x7;
+	*(pbuffer +  16) = pdata->ana_config__vcsel_pulse_width_offset & 0x1F;
+	*(pbuffer +  17) = pdata->ana_config__fast_osc__config_ctrl & 0x1;
+	*(pbuffer +  18) = pdata->sigma_estimator__effective_pulse_width_ns;
+	*(pbuffer +  19) = pdata->sigma_estimator__effective_ambient_width_ns;
+	*(pbuffer +  20) = pdata->sigma_estimator__sigma_ref_mm;
+	*(pbuffer +  21) = pdata->algo__crosstalk_compensation_valid_height_mm;
+	*(pbuffer +  22) = pdata->spare_host_config__static_config_spare_0;
+	*(pbuffer +  23) = pdata->spare_host_config__static_config_spare_1;
+	VL53LX_i2c_encode_uint16_t(pdata->algo__range_ignore_threshold_mcps, 2, pbuffer + 24);
+	*(pbuffer +  26) = pdata->algo__range_ignore_valid_height_mm;
+	*(pbuffer +  27) = pdata->algo__range_min_clip;
+	*(pbuffer +  28) = pdata->algo__consistency_check__tolerance & 0xF;
+	*(pbuffer +  29) = pdata->spare_host_config__static_config_spare_2;
+	*(pbuffer +  30) = pdata->sd_config__reset_stages_msb & 0xF;
+	*(pbuffer +  31) = pdata->sd_config__reset_stages_lsb;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_i2c_encode_general_config(VL53LX_general_config_t *pdata, uint16_t buf_size, uint8_t *pbuffer)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (buf_size < VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES)
+		return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
+
+	*(pbuffer +   0) = pdata->gph_config__stream_count_update_value;
+	*(pbuffer +   1) = pdata->global_config__stream_divider;
+	*(pbuffer +   2) = pdata->system__interrupt_config_gpio;
+	*(pbuffer +   3) = pdata->cal_config__vcsel_start & 0x7F;
+	VL53LX_i2c_encode_uint16_t(pdata->cal_config__repeat_rate & 0xFFF, 2, pbuffer + 4);
+	*(pbuffer +   6) = pdata->global_config__vcsel_width & 0x7F;
+	*(pbuffer +   7) = pdata->phasecal_config__timeout_macrop;
+	*(pbuffer +   8) = pdata->phasecal_config__target;
+	*(pbuffer +   9) = pdata->phasecal_config__override & 0x1;
+	*(pbuffer +  11) = 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 + 14);
+	VL53LX_i2c_encode_uint16_t(pdata->dss_config__manual_effective_spads_select, 2, pbuffer + 16);
+	*(pbuffer +  18) = pdata->dss_config__manual_block_select;
+	*(pbuffer +  19) = pdata->dss_config__aperture_attenuation;
+	*(pbuffer +  20) = pdata->dss_config__max_spads_limit;
+	*(pbuffer +  21) = 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    = 0;
+	uint32_t   VL53LX_p_003 = 0;
+
+	VL53LX_p_003 =  ip_value;
+
+	for (i = 0; i < count; i++) {
+		pbuffer[count-i-1] = (uint8_t)(VL53LX_p_003 & 0x00FF);
+		VL53LX_p_003 = VL53LX_p_003 >> 8;
+	}
+}
+
+uint32_t VL53LX_i2c_decode_uint32_t(uint16_t count, uint8_t *pbuffer)
+{
+	uint32_t   value = 0x00;
+
+	while (count-- > 0)
+		value = (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 = VL53LX_ERROR_NONE;
+
+	if (buf_size < VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES)
+		return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
+
+	*(pbuffer +   0) = pdata->mm_config__timeout_macrop_a_hi & 0xF;
+	*(pbuffer +   1) = pdata->mm_config__timeout_macrop_a_lo;
+	*(pbuffer +   2) = pdata->mm_config__timeout_macrop_b_hi & 0xF;
+	*(pbuffer +   3) = pdata->mm_config__timeout_macrop_b_lo;
+	*(pbuffer +   4) = pdata->range_config__timeout_macrop_a_hi & 0xF;
+	*(pbuffer +   5) = pdata->range_config__timeout_macrop_a_lo;
+	*(pbuffer +   6) = pdata->range_config__vcsel_period_a & 0x3F;
+	*(pbuffer +   7) = pdata->range_config__timeout_macrop_b_hi & 0xF;
+	*(pbuffer +   8) = pdata->range_config__timeout_macrop_b_lo;
+	*(pbuffer +   9) = 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) = pdata->range_config__valid_phase_low;
+	*(pbuffer +  15) = pdata->range_config__valid_phase_high;
+	VL53LX_i2c_encode_uint32_t(pdata->system__intermeasurement_period, 4, pbuffer + 18);
+	*(pbuffer +  22) = pdata->system__fractional_enable & 0x1;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_i2c_encode_dynamic_config(VL53LX_dynamic_config_t *pdata, uint16_t buf_size, uint8_t *pbuffer)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (buf_size < VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES)
+		return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
+
+	*(pbuffer +   0) = 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) = pdata->system__enable_xtalk_per_quadrant & 0x1;
+	*(pbuffer +   6) = pdata->system__seed_config & 0x7;
+	*(pbuffer +   7) = pdata->sd_config__woi_sd0;
+	*(pbuffer +   8) = pdata->sd_config__woi_sd1;
+	*(pbuffer +   9) = pdata->sd_config__initial_phase_sd0 & 0x7F;
+	*(pbuffer +  10) = pdata->sd_config__initial_phase_sd1 & 0x7F;
+	*(pbuffer +  11) = pdata->system__grouped_parameter_hold_1 & 0x3;
+	*(pbuffer +  12) = pdata->sd_config__first_order_select & 0x3;
+	*(pbuffer +  13) = pdata->sd_config__quantifier & 0xF;
+	*(pbuffer +  14) = pdata->roi_config__user_roi_centre_spad;
+	*(pbuffer +  15) = pdata->roi_config__user_roi_requested_global_xy_size;
+	*(pbuffer +  16) = pdata->system__sequence_config;
+	*(pbuffer +  17) = 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 *pinternal_stream_count_val)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint8_t stream_divider;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	stream_divider = pdev->gen_cfg.global_config__stream_divider;
+
+	if (stream_divider == 0) {
+		*pinternal_stream_count = external_stream_count;
+	} else if (*pinternal_stream_count_val == (stream_divider-1)) {
+		if (*pinternal_stream_count == 0xFF)
+			*pinternal_stream_count = 0x80;
+		else
+			*pinternal_stream_count = *pinternal_stream_count + 1;
+		*pinternal_stream_count_val = 0;
+
+	} else {
+		*pinternal_stream_count_val = *pinternal_stream_count_val + 1;
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_update_ll_driver_rd_state(VL53LX_DEV Dev)
+{
+	VL53LX_Error        status  = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state);
+
+	if ((pdev->sys_ctrl.system__mode_start & VL53LX_DEVICEMEASUREMENTMODE_MODE_MASK) == 0x00) {
+		pstate->rd_device_state  = VL53LX_DEVICESTATE_SW_STANDBY;
+		pstate->rd_stream_count  = 0;
+		pstate->rd_internal_stream_count = 0;
+		pstate->rd_internal_stream_count_val = 0;
+		pstate->rd_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
+		pstate->rd_timing_status = 0;
+		pstate->rd_zone_id       = 0;
+
+	} else {
+		if (pstate->rd_stream_count == 0xFF)
+			pstate->rd_stream_count = 0x80;
+		else
+			pstate->rd_stream_count++;
+
+		status = VL53LX_update_internal_stream_counters(Dev, pstate->rd_stream_count, &(pstate->rd_internal_stream_count), &(pstate->rd_internal_stream_count_val));
+		pstate->rd_gph_id ^= VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
+		switch (pstate->rd_device_state) {
+		case VL53LX_DEVICESTATE_SW_STANDBY:
+			if ((pdev->dyn_cfg.system__grouped_parameter_hold & VL53LX_GROUPEDPARAMETERHOLD_ID_MASK) > 0) {
+				pstate->rd_device_state =
+				VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC;
+			} else {
+				if (pstate->rd_zone_id >= pdev->zone_cfg.active_zones)
+					pstate->rd_device_state = VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA;
+				else
+					pstate->rd_device_state = VL53LX_DEVICESTATE_RANGING_GATHER_DATA;
+			}
+			pstate->rd_stream_count  = 0;
+			pstate->rd_internal_stream_count = 0;
+			pstate->rd_internal_stream_count_val = 0;
+			pstate->rd_timing_status = 0;
+			pstate->rd_zone_id       = 0;
+			break;
+		case VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC:
+			pstate->rd_stream_count = 0;
+			pstate->rd_internal_stream_count = 0;
+			pstate->rd_internal_stream_count_val = 0;
+			pstate->rd_zone_id      = 0;
+			if (pstate->rd_zone_id >= pdev->zone_cfg.active_zones)
+				pstate->rd_device_state = VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA;
+			else
+				pstate->rd_device_state = VL53LX_DEVICESTATE_RANGING_GATHER_DATA;
+			break;
+		case VL53LX_DEVICESTATE_RANGING_GATHER_DATA:
+			pstate->rd_zone_id++;
+			if (pstate->rd_zone_id >= pdev->zone_cfg.active_zones)
+				pstate->rd_device_state = VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA;
+			else
+				pstate->rd_device_state = VL53LX_DEVICESTATE_RANGING_GATHER_DATA;
+			break;
+		case VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA:
+			pstate->rd_zone_id        = 0;
+			pstate->rd_timing_status ^= 0x01;
+			if (pstate->rd_zone_id >= pdev->zone_cfg.active_zones)
+				pstate->rd_device_state = VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA;
+			else
+				pstate->rd_device_state = VL53LX_DEVICESTATE_RANGING_GATHER_DATA;
+			break;
+		default:
+			pstate->rd_device_state  = VL53LX_DEVICESTATE_SW_STANDBY;
+			pstate->rd_stream_count  = 0;
+			pstate->rd_internal_stream_count = 0;
+			pstate->rd_internal_stream_count_val = 0;
+			pstate->rd_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
+			pstate->rd_timing_status = 0;
+			pstate->rd_zone_id       = 0;
+			break;
+		}
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_update_ll_driver_cfg_state(VL53LX_DEV Dev)
+{
+	VL53LX_Error         status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t  *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t  *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+
+	VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state);
+	VL53LX_zone_private_dyn_cfgs_t *pZ = &(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_MODE_MASK) == 0x00) {
+		pstate->cfg_device_state  = VL53LX_DEVICESTATE_SW_STANDBY;
+		pstate->cfg_stream_count  = 0;
+		pstate->cfg_internal_stream_count = 0;
+		pstate->cfg_internal_stream_count_val = 0;
+		pstate->cfg_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
+		pstate->cfg_timing_status = 0;
+		pstate->cfg_zone_id       = 0;
+		prev_cfg_zone_id          = 0;
+		prev_cfg_gph_id           = 0;
+		prev_cfg_stream_count     = 0;
+
+	} else {
+		prev_cfg_gph_id           = pstate->cfg_gph_id;
+		prev_cfg_zone_id          = pstate->cfg_zone_id;
+		prev_cfg_stream_count     = pstate->cfg_stream_count;
+
+		if (pstate->cfg_stream_count == 0xFF)
+			pstate->cfg_stream_count = 0x80;
+		else
+			pstate->cfg_stream_count++;
+
+		status = VL53LX_update_internal_stream_counters(Dev, pstate->cfg_stream_count, &(pstate->cfg_internal_stream_count), &(pstate->cfg_internal_stream_count_val));
+
+		pstate->cfg_gph_id ^= VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
+
+		switch (pstate->cfg_device_state) {
+		case VL53LX_DEVICESTATE_SW_STANDBY:
+			pstate->cfg_zone_id = 1;
+			if (pstate->cfg_zone_id > pdev->zone_cfg.active_zones) {
+				pstate->cfg_zone_id = 0;
+				pstate->cfg_timing_status ^= 0x01;
+			}
+			pstate->cfg_stream_count = 1;
+
+			if (pdev->gen_cfg.global_config__stream_divider == 0) {
+				pstate->cfg_internal_stream_count = 1;
+				pstate->cfg_internal_stream_count_val = 0;
+			} else {
+				pstate->cfg_internal_stream_count = 0;
+				pstate->cfg_internal_stream_count_val = 1;
+			}
+			pstate->cfg_device_state = 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 = 0;
+				pstate->cfg_timing_status ^= 0x01;
+
+				if (pdev->zone_cfg.active_zones > 0) {
+					pstate->cfg_device_state =
+					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 = 0;
+				pstate->cfg_timing_status ^= 0x01;
+			}
+			break;
+		default:
+			pstate->cfg_device_state = VL53LX_DEVICESTATE_SW_STANDBY;
+			pstate->cfg_stream_count = 0;
+			pstate->cfg_internal_stream_count = 0;
+			pstate->cfg_internal_stream_count_val = 0;
+			pstate->cfg_gph_id = VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
+			pstate->cfg_timing_status = 0;
+			pstate->cfg_zone_id       = 0;
+			break;
+		}
+	}
+	if (pdev->zone_cfg.active_zones == 0) {
+		pZ->VL53LX_p_003[prev_cfg_zone_id].expected_stream_count = prev_cfg_stream_count - 1;
+		pZ->VL53LX_p_003[pstate->rd_zone_id].expected_gph_id = prev_cfg_gph_id ^ VL53LX_GROUPEDPARAMETERHOLD_ID_MASK;
+	} else {
+		pZ->VL53LX_p_003[prev_cfg_zone_id].expected_stream_count = prev_cfg_stream_count;
+		pZ->VL53LX_p_003[prev_cfg_zone_id].expected_gph_id = prev_cfg_gph_id;
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_init_and_start_range(VL53LX_DEV Dev, uint8_t measurement_mode, VL53LX_DeviceConfigLevel device_config_level)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t  *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+
+	uint8_t buffer[VL53LX_MAX_I2C_XFER_SIZE];
+
+	VL53LX_static_nvm_managed_t   *pstatic_nvm   = &(pdev->stat_nvm);
+	VL53LX_customer_nvm_managed_t *pcustomer_nvm = &(pdev->customer);
+	VL53LX_static_config_t        *pstatic       = &(pdev->stat_cfg);
+	VL53LX_general_config_t       *pgeneral      = &(pdev->gen_cfg);
+	VL53LX_timing_config_t        *ptiming       = &(pdev->tim_cfg);
+	VL53LX_dynamic_config_t       *pdynamic      = &(pdev->dyn_cfg);
+	VL53LX_system_control_t       *psystem       = &(pdev->sys_ctrl);
+
+	VL53LX_ll_driver_state_t  *pstate   = &(pdev->ll_state);
+	VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
+
+	uint8_t  *pbuffer                   = &buffer[0];
+	uint16_t i                          = 0;
+	uint16_t i2c_index                  = 0;
+	uint16_t i2c_buffer_offset_bytes    = 0;
+	uint16_t i2c_buffer_size_bytes      = 0;
+
+	pdev->measurement_mode = measurement_mode;
+
+	psystem->system__mode_start = (psystem->system__mode_start & VL53LX_DEVICEMEASUREMENTMODE_STOP_MASK) | measurement_mode;
+
+	status = VL53LX_set_user_zone(Dev, &(pdev->zone_cfg.user_zones[pdev->ll_state.cfg_zone_id]));
+	if (pdev->zone_cfg.active_zones > 0) {
+		status = 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_HISTOGRAM) == 0x00) && (pdev->xtalk_cfg.global_crosstalk_compensation_enable == 0x01)) {
+		pdev->stat_cfg.algo__range_ignore_threshold_mcps = pdev->xtalk_cfg.crosstalk_range_ignore_threshold_rate_mcps;
+	}
+
+	if (pdev->low_power_auto_data.low_power_auto_range_count == 0xFF)
+		pdev->low_power_auto_data.low_power_auto_range_count = 0x0;
+
+	if ((pdev->low_power_auto_data.is_low_power_auto_mode == 1) && (pdev->low_power_auto_data.low_power_auto_range_count == 0)) {
+		pdev->low_power_auto_data.saved_interrupt_config = pdev->gen_cfg.system__interrupt_config_gpio;
+		pdev->gen_cfg.system__interrupt_config_gpio = 1 << 5;
+		if ((pdev->dyn_cfg.system__sequence_config & (VL53LX_SEQUENCE_MM1_EN | VL53LX_SEQUENCE_MM2_EN)) == 0x0) {
+			pN->algo__part_to_part_range_offset_mm = (pN->mm_config__outer_offset_mm << 2);
+		} else {
+			pN->algo__part_to_part_range_offset_mm = 0x0;
+		}
+		if (device_config_level < VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS) {
+			device_config_level = VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS;
+		}
+	}
+
+	if ((pdev->low_power_auto_data.is_low_power_auto_mode == 1) && (pdev->low_power_auto_data.low_power_auto_range_count == 1)) {
+		pdev->gen_cfg.system__interrupt_config_gpio = pdev->low_power_auto_data.saved_interrupt_config;
+		device_config_level = VL53LX_DEVICECONFIGLEVEL_FULL;
+	}
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_save_cfg_data(Dev);
+
+	switch (device_config_level) {
+	case VL53LX_DEVICECONFIGLEVEL_FULL:
+		i2c_index = VL53LX_STATIC_NVM_MANAGED_I2C_INDEX;
+		break;
+	case VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS:
+		i2c_index = VL53LX_CUSTOMER_NVM_MANAGED_I2C_INDEX;
+		break;
+	case VL53LX_DEVICECONFIGLEVEL_STATIC_ONWARDS:
+		i2c_index = VL53LX_STATIC_CONFIG_I2C_INDEX;
+		break;
+	case VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS:
+		i2c_index = VL53LX_GENERAL_CONFIG_I2C_INDEX;
+		break;
+	case VL53LX_DEVICECONFIGLEVEL_TIMING_ONWARDS:
+		i2c_index = VL53LX_TIMING_CONFIG_I2C_INDEX;
+		break;
+	case VL53LX_DEVICECONFIGLEVEL_DYNAMIC_ONWARDS:
+		i2c_index = VL53LX_DYNAMIC_CONFIG_I2C_INDEX;
+		break;
+	default:
+		i2c_index = VL53LX_SYSTEM_CONTROL_I2C_INDEX;
+		break;
+	}
+	i2c_buffer_size_bytes = (VL53LX_SYSTEM_CONTROL_I2C_INDEX + VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES) - i2c_index;
+
+	pbuffer = &buffer[0];
+	for (i = 0; i < i2c_buffer_size_bytes; i++)
+		*pbuffer++ = 0;
+
+	if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_FULL && status == VL53LX_ERROR_NONE) {
+		i2c_buffer_offset_bytes = VL53LX_STATIC_NVM_MANAGED_I2C_INDEX - i2c_index;
+		status = VL53LX_i2c_encode_static_nvm_managed(pstatic_nvm, VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]);
+	}
+	if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS && status == VL53LX_ERROR_NONE) {
+		i2c_buffer_offset_bytes = VL53LX_CUSTOMER_NVM_MANAGED_I2C_INDEX - i2c_index;
+		status = VL53LX_i2c_encode_customer_nvm_managed(pcustomer_nvm, VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]);
+	}
+	if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_STATIC_ONWARDS && status == VL53LX_ERROR_NONE) {
+		i2c_buffer_offset_bytes = VL53LX_STATIC_CONFIG_I2C_INDEX - i2c_index;
+		status = VL53LX_i2c_encode_static_config(pstatic, VL53LX_STATIC_CONFIG_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]);
+	}
+	if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS && status == VL53LX_ERROR_NONE) {
+		i2c_buffer_offset_bytes = VL53LX_GENERAL_CONFIG_I2C_INDEX - i2c_index;
+		status = VL53LX_i2c_encode_general_config(pgeneral, VL53LX_GENERAL_CONFIG_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]);
+	}
+	if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_TIMING_ONWARDS && status == VL53LX_ERROR_NONE) {
+		i2c_buffer_offset_bytes = VL53LX_TIMING_CONFIG_I2C_INDEX - i2c_index;
+		status = VL53LX_i2c_encode_timing_config(ptiming, VL53LX_TIMING_CONFIG_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]);
+	}
+	if (device_config_level >= VL53LX_DEVICECONFIGLEVEL_DYNAMIC_ONWARDS && status == VL53LX_ERROR_NONE) {
+		i2c_buffer_offset_bytes = VL53LX_DYNAMIC_CONFIG_I2C_INDEX - i2c_index;
+		if ((psystem->system__mode_start & VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK) == VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK) {
+			pdynamic->system__grouped_parameter_hold_0 = pstate->cfg_gph_id | 0x01;
+			pdynamic->system__grouped_parameter_hold_1 = pstate->cfg_gph_id | 0x01;
+			pdynamic->system__grouped_parameter_hold   = pstate->cfg_gph_id;
+		}
+		status = VL53LX_i2c_encode_dynamic_config(pdynamic, VL53LX_DYNAMIC_CONFIG_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]);
+	}
+	if (status == VL53LX_ERROR_NONE) {
+		i2c_buffer_offset_bytes = VL53LX_SYSTEM_CONTROL_I2C_INDEX - i2c_index;
+		status = VL53LX_i2c_encode_system_control(psystem, VL53LX_SYSTEM_CONTROL_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes]);
+	}
+	if (status == VL53LX_ERROR_NONE) {
+		status = VL53LX_WriteMulti(Dev, i2c_index, buffer, (uint32_t)i2c_buffer_size_bytes);
+	}
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_update_ll_driver_rd_state(Dev);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_update_ll_driver_cfg_state(Dev);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_StartMeasurement(VL53LX_DEV Dev)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	uint8_t DeviceMeasurementMode;
+	uint8_t i;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	VL53LX_load_patch(Dev);
+	for (i = 0; i < VL53LX_MAX_RANGE_RESULTS; i++) {
+		pdev->PreviousRangeMilliMeter[i] = 0;
+		pdev->PreviousRangeStatus[i] = 255;
+		pdev->PreviousExtendedRange[i] = 0;
+	}
+	pdev->PreviousStreamCount = 0;
+	pdev->PreviousRangeActiveResults = 0;
+
+	DeviceMeasurementMode = VL53LXDevDataGet(Dev, LLData.measurement_mode);
+
+	if (Status == VL53LX_ERROR_NONE)
+		Status = VL53LX_init_and_start_range(Dev, DeviceMeasurementMode, VL53LX_DEVICECONFIGLEVEL_FULL);
+
+	return Status;
+}
+
+VL53LX_Error VL53LX_WaitMeasurementDataReady(VL53LX_DEV Dev)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+
+	Status = 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 = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	uint8_t  gpio__mux_active_high_hv = 0;
+	uint8_t  gpio__tio_hv_status      = 0;
+	uint8_t  interrupt_ready          = 0;
+
+	gpio__mux_active_high_hv = pdev->stat_cfg.gpio_hv_mux__ctrl & VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_MASK;
+
+	if (gpio__mux_active_high_hv == VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH)
+		interrupt_ready = 0x01;
+	else
+		interrupt_ready = 0x00;
+
+	status = VL53LX_RdByte(Dev, VL53LX_GPIO__TIO_HV_STATUS, &gpio__tio_hv_status);
+
+	if ((gpio__tio_hv_status & 0x01) == interrupt_ready)
+		*pready = 0x01;
+	else
+		*pready = 0x00;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_GetMeasurementDataReady(VL53LX_DEV Dev, uint8_t *pMeasurementDataReady)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+
+	Status = VL53LX_is_new_data_ready(Dev, pMeasurementDataReady);
+
+	return Status;
+}
+
+long stmvl53lx_tv_dif(struct st_timeval *pstart_tv, struct st_timeval *pstop_tv)
+{
+	long total_sec, total_usec;
+
+	total_sec = pstop_tv->tv_sec - pstart_tv->tv_sec;
+	total_usec = (pstop_tv->tv_usec - pstart_tv->tv_usec);
+
+	return total_sec*1000000+total_usec;
+}
+
+VL53LX_Error VL53LX_GetMultiRangingData(VL53LX_DEV Dev, VL53LX_MultiRangingData_t *pMultiRangingData)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_range_results_t *presults = (VL53LX_range_results_t *) pdev->wArea1;
+
+	memset(pMultiRangingData, 0xFF, sizeof(VL53LX_MultiRangingData_t));
+
+	Status = VL53LX_get_device_results(Dev, VL53LX_DEVICERESULTSLEVEL_FULL, presults);
+	Status = SetMeasurementData(Dev, presults, pMultiRangingData);
+
+	return Status;
+}
+
+VL53LX_Error VL53LX_get_histogram_debug_data(VL53LX_DEV Dev, VL53LX_histogram_bin_data_t *pdata)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = 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 = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdata->preset_mode             = pdev->preset_mode;
+	pdata->zone_preset             = pdev->zone_preset;
+	pdata->measurement_mode        = pdev->measurement_mode;
+	pdata->offset_calibration_mode = pdev->offset_calibration_mode;
+	pdata->offset_correction_mode  = pdev->offset_correction_mode;
+	pdata->dmax_mode               = pdev->dmax_mode;
+
+	pdata->phasecal_config_timeout_us  = pdev->phasecal_config_timeout_us;
+	pdata->mm_config_timeout_us        = pdev->mm_config_timeout_us;
+	pdata->range_config_timeout_us     = pdev->range_config_timeout_us;
+	pdata->inter_measurement_period_ms = pdev->inter_measurement_period_ms;
+	pdata->dss_config__target_total_rate_mcps = pdev->dss_config__target_total_rate_mcps;
+
+	status = VL53LX_get_histogram_debug_data(Dev, &(pdata->VL53LX_p_006));
+
+	return status;
+}
+
+VL53LX_Error VL53LX_GetAdditionalData(VL53LX_DEV Dev, VL53LX_AdditionalData_t *pAdditionalData)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+
+	Status = 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 = meas->HasXtalkValueChanged ? true : data->is_xtalk_value_changed;
+}
+
+static void stmvl53lx_input_push_data_multiobject(struct stmvl53lx_data *data)
+{
+	VL53LX_MultiRangingData_t *mmeas = &data->meas.multi_range_data;
+	int i;
+	int rc = 0;
+	VL53LX_TargetRangeData_t *meas_array[4];
+	VL53LX_CalibrationData_t calibration_data;
+	struct st_timeval tv;
+	struct input_dev *input = data->input_dev_ps;
+
+	st_gettimeofday(&tv);
+
+	for (i = 0; i < 4; i++)
+		meas_array[i] = &mmeas->RangeData[i];
+
+	rc = 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 = %d\n", meas_array[0]->AmbientRateRtnMegaCps);
+
+	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->HasXtalkValueChanged, mmeas->StreamCount, mmeas->NumberOfObjectsFound);
+
+	input_report_abs(input, ABS_TILT_Y,   0);
+	input_report_abs(input, ABS_TOOL_WIDTH, calibration_data.customer.algo__crosstalk_compensation_plane_offset_kcps);
+
+	vl53lx_dbgmsg("ABS_TOOL_WIDTH Xtalk = %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->EffectiveSpadRtnCount, meas_array[1]->RangeStatus, meas_array[0]->RangeStatus);
+	vl53lx_dbgmsg("ABS_BRAKE : 0x%X\n", (mmeas->EffectiveSpadRtnCount & 0xFFFF) << 16 | ((meas_array[1]->RangeStatus) << 8) | meas_array[0]->RangeStatus);
+
+	if (mmeas->NumberOfObjectsFound == 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 << 16 | 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 = 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 = data->input_dev_ps;
+
+	st_gettimeofday(&data->meas.comp_tv);
+	ts_msec = stmvl53lx_tv_dif(&data->start_tv, &data->meas.comp_tv)/1000;
+
+	pmrange = &data->meas.multi_range_data;
+	tmprange = &data->meas.tmp_range_data;
+
+	for (i = 0; i < VL53LX_MAX_RANGE_RESULTS; i++)
+		memcpy(&RangeData[i], &pmrange->RangeData[i], sizeof(VL53LX_TargetRangeData_t));
+
+	data->meas.intr++;
+
+	rc = VL53LX_GetMultiRangingData(&data->stdev, &data->meas.tmp_range_data);
+
+	if (tmprange->NumberOfObjectsFound == 0)
+		tmprange->RangeData[0].RangeStatus = VL53LX_RANGESTATUS_NONE;
+
+	memcpy(pmrange, tmprange, sizeof(VL53LX_MultiRangingData_t));
+
+	if (!rc)
+		rc = VL53LX_GetAdditionalData(&data->stdev, &data->meas.additional_data);
+	detect_xtalk_value_change(data, pmrange);
+
+	if (data->enable_sensor == 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.err_cnt, data->meas.err_tot);
+			_ctrl_stop(data);
+			input_report_abs(input, ABS_MISC, ABNORMAL_STOP_3);
+			input_sync(input);
+		}
+		return;
+	}
+
+	pmrange->TimeStamp = ts_msec;
+	for (i = 1; i < pmrange->NumberOfObjectsFound; i++)
+		pmrange->TimeStamp = ts_msec;
+
+	data->meas.cnt++;
+	vl53lx_dbgmsg("#%3d %2d poll ts %5d status=%d obj cnt=%d\n",
+		data->meas.cnt,
+		data->meas.poll_cnt,
+		pmrange->TimeStamp,
+		pmrange->RangeData[0].RangeStatus,
+		pmrange->NumberOfObjectsFound);
+
+	data->is_data_valid = true;
+
+	wake_up_data_waiters(data);
+
+	stmvl53lx_input_push_data(data);
+	stmvl53lx_insert_flush_events_lock(data);
+
+	data->meas.start_tv = data->meas.comp_tv;
+	data->meas.poll_cnt = 0;
+	data->meas.err_cnt = 0;
+}
+
+VL53LX_Error VL53LX_clear_interrupt_and_enable_next_range(VL53LX_DEV Dev, uint8_t measurement_mode)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_and_start_range(Dev, measurement_mode, VL53LX_DEVICECONFIGLEVEL_GENERAL_ONWARDS);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_ClearInterruptAndStartMeasurement(VL53LX_DEV Dev)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	uint8_t DeviceMeasurementMode;
+
+	DeviceMeasurementMode = VL53LXDevDataGet(Dev, LLData.measurement_mode);
+
+	Status = VL53LX_clear_interrupt_and_enable_next_range(Dev, DeviceMeasurementMode);
+	return Status;
+}
+
+static int stmvl53lx_intr_process(struct stmvl53lx_data *data)
+{
+	uint8_t data_rdy;
+	int rc = 0;
+	struct st_timeval tv_now;
+	struct input_dev *input = data->input_dev_ps;
+
+	if (!data->enable_sensor)
+		goto done;
+
+	data->meas.poll_cnt++;
+	rc = 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 = 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 = false;
+	else
+		stmvl53lx_on_newdata_event(data);
+
+	if (data->enable_sensor) {
+		work_dbg("intr clr");
+		data->is_delay_allowed = data->allow_hidden_start_stop;
+		rc = VL53LX_ClearInterruptAndStartMeasurement(&data->stdev);
+		data->is_delay_allowed = 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 = 0;
+
+	mutex_lock(&data->work_mutex);
+	if (data->enable_sensor) {
+		rc = stmvl53lx_intr_process(data);
+	} else {
+		vl53lx_dbgmsg("got intr but not on (dummy or calibration)\n");
+		rc = 0;
+	}
+
+	mutex_unlock(&data->work_mutex);
+	return rc;
+}
+
+static irqreturn_t stmvl53lx_irq_handler_i2c(int vec, void *info)
+{
+	struct i2c_data *i2c_data = (struct i2c_data *)info;
+
+	if (i2c_data->irq == 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 != %d\n", vec, i2c_data->irq);
+			i2c_data->msg_flag.unhandled_irq_vec = 1;
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+static void memory_release(struct kref *kref)
+{
+	struct i2c_data *data = 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 = 0;
+
+	if (!data->reset_state)
+		return 0;
+
+	rc = stmvl53lx_module_func_tbl.reset_release(data->client_object);
+	if (rc)
+		vl53lx_errmsg("reset release fail rc=%d\n", rc);
+	else
+		data->reset_state = 0;
+
+	return rc;
+}
+
+static int stmvl53lx_start(struct stmvl53lx_data *data)
+{
+	int rc = 0;
+
+	data->is_first_irq = true;
+	data->is_data_valid = false;
+	data->is_xtalk_value_changed = false;
+
+	rc = reset_release(data);
+	if (rc)
+		goto done;
+
+	rc = stmvl53lx_sendparams(data);
+	if (rc)
+		goto done;
+
+	st_gettimeofday(&data->start_tv);
+	data->meas.start_tv = data->start_tv;
+	kill_mz_data(&data->meas.multi_range_data);
+
+	data->allow_hidden_start_stop = false;
+
+	rc = VL53LX_StartMeasurement(&data->stdev);
+	if (rc) {
+		vl53lx_errmsg("VL53LX_StartMeasurement @%d fail %d", __LINE__, rc);
+		rc = store_last_error(data, rc);
+		goto done;
+	}
+
+	data->meas.cnt = 0;
+	data->meas.err_cnt = 0;
+	data->meas.err_tot = 0;
+	data->meas.poll_cnt = 0;
+	data->meas.intr = 0;
+	data->enable_sensor = 1;
+	if (data->poll_mode) {
+		schedule_delayed_work(&data->dwork, msecs_to_jiffies(data->poll_delay_ms));
+	}
+
+done:
+	data->is_first_start_done = true;
+	return rc;
+}
+
+static int ctrl_start(struct stmvl53lx_data *data)
+{
+	int rc = 0;
+
+	mutex_lock(&data->work_mutex);
+
+	if (data->is_device_remove) {
+		rc = -ENODEV;
+		goto done;
+	}
+
+	vl53lx_dbgmsg(" state = %d\n", data->enable_sensor);
+	if (data->enable_sensor == 0 && !data->is_calibrating) {
+		rc = stmvl53lx_start(data);
+	} else {
+		rc = -EBUSY;
+	}
+	vl53lx_dbgmsg(" final state = %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 = %u\n", data->flushCount);
+		data->flush_todo_counter--;
+	}
+}
+
+static int _ctrl_stop(struct stmvl53lx_data *data)
+{
+	int rc = 0;
+
+	vl53lx_dbgmsg("enter state = %d\n", data->enable_sensor);
+	data->is_data_valid = true;
+	if (data->enable_sensor == 1) {
+		rc = stmvl53lx_stop(data);
+	} else {
+		vl53lx_dbgmsg("already off did nothing\n");
+		rc = 0;
+	}
+	stmvl53lx_insert_flush_events_lock(data);
+	vl53lx_dbgmsg("	final state = %d\n", data->enable_sensor);
+
+	return rc;
+}
+
+static int ctrl_stop(struct stmvl53lx_data *data)
+{
+	int rc = 0;
+
+	mutex_lock(&data->work_mutex);
+
+	if (data->is_device_remove) {
+		rc = -ENODEV;
+		goto done;
+	}
+	if (data->enable_sensor)
+		rc = _ctrl_stop(data);
+	else
+		rc = -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 = 0;
+
+	if (data->is_device_remove)
+		return -ENODEV;
+
+	total_byte = offsetof(struct stmvl53lx_register, data.b);
+	if (copy_from_user(&reg, 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 = offsetof(struct stmvl53lx_register, data.bytes[reg.cnt]);
+	if (!reg.is_read) {
+		if (copy_from_user(&reg, p, total_byte)) {
+			vl53lx_errmsg(" data cpy fail\n");
+			return -EFAULT;
+		}
+	}
+
+	if (!reg.is_read) {
+		rc = VL53LX_WriteMulti(&data->stdev, (uint16_t)reg.index, reg.data.bytes, reg.cnt);
+		reg.status = rc;
+		total_byte = offsetof(struct stmvl53lx_register, data.b);
+		vl53lx_dbgmsg("wr %x %d bytes statu %d\n", reg.index, reg.cnt, rc);
+		if (rc)
+			rc = store_last_error(data, rc);
+	} else {
+		rc = VL53LX_ReadMulti(&data->stdev, (uint16_t)reg.index, reg.data.bytes, reg.cnt);
+		reg.status = rc;
+		vl53lx_dbgmsg("rd %x %d bytes status %d\n", reg.index, reg.cnt, rc);
+		if (rc) {
+			total_byte = offsetof(struct stmvl53lx_register, data.b);
+			rc = store_last_error(data, rc);
+		}
+	}
+
+	if (copy_to_user(p, &reg, total_byte)) {
+		vl53lx_errmsg("%d, fail\n", __LINE__);
+		return -EFAULT;
+	}
+	return rc;
+}
+
+static int reset_hold(struct stmvl53lx_data *data)
+{
+	int rc = 0;
+
+	if (data->reset_state)
+		return 0;
+
+	if (data->force_device_on_en)
+		return 0;
+
+	rc = stmvl53lx_module_func_tbl.reset_hold(data->client_object);
+	if (!rc)
+		data->reset_state = 1;
+
+	return rc;
+}
+
+static ssize_t stmvl53lx_show_enable_ps_sensor(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct stmvl53lx_data *data = 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 = 0;
+	unsigned long val;
+	struct stmvl53lx_data *data = dev_get_drvdata(dev);
+
+	rc = kstrtoul(buf, 10, &val);
+	if (rc) {
+		vl53lx_errmsg("enable sensor syntax in %s\n", buf);
+		return -EINVAL;
+	}
+	if (val == 1) {
+		rc = ctrl_start(data);
+	} else if (val == 0) {
+		rc = 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 = 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 delay)
+{
+	int rc = 0;
+
+	if (delay <= 0)
+		rc = -EINVAL;
+	else
+		data->poll_delay_ms = delay;
+
+	return rc;
+}
+
+IMPLEMENT_PARAMETER_INTEGER(poll_delay_ms, "poll delay ms")
+
+static DEVICE_ATTR(set_delay_ms, 0660, stmvl53lx_show_poll_delay_ms, stmvl53lx_store_poll_delay_ms);
+
+static int stmvl53lx_set_timing_budget(struct stmvl53lx_data *data, int timing)
+{
+	int rc = 0;
+
+	if (timing <= 0) {
+		vl53lx_errmsg("invalid timing valid %d\n", timing);
+		rc = -EINVAL;
+	} else if (data->enable_sensor) {
+		rc = VL53LX_SetMeasurementTimingBudgetMicroSeconds(&data->stdev,
+			timing);
+		if (rc) {
+			vl53lx_errmsg("SetTimingBudget %d fail %d", timing, rc);
+			rc = store_last_error(data, rc);
+		} else
+			data->timing_budget = timing;
+	} else
+		data->timing_budget = timing;
+
+	return rc;
+}
+
+IMPLEMENT_PARAMETER_INTEGER(timing_budget, "timing budget")
+
+static DEVICE_ATTR(timing_budget, 0660, stmvl53lx_show_timing_budget, stmvl53lx_store_timing_budget);
+
+static ssize_t stmvl53lx_show_roi(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int n;
+	struct stmvl53lx_data *data = dev_get_drvdata(dev);
+
+	mutex_lock(&data->work_mutex);
+	n = 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_attribute *attr, const char *buf, size_t count)
+{
+	int rc;
+	int n;
+	int tlx, tly, brx, bry;
+	struct stmvl53lx_data *data = dev_get_drvdata(dev);
+
+	mutex_lock(&data->work_mutex);
+	if (data->enable_sensor) {
+		vl53lx_errmsg("ERROR can't set roi while ranging");
+		rc = -EBUSY;
+	} else {
+		n = sscanf(buf, "%d %d %d %d", &tlx, &tly, &brx, &bry);
+		if (n == 4) {
+			data->roi_cfg.TopLeftX = tlx;
+			data->roi_cfg.TopLeftY = tly;
+			data->roi_cfg.BotRightX = brx;
+			data->roi_cfg.BotRightY = bry;
+			rc = count;
+			vl53lx_dbgmsg("ROI %2d %2d %2d %2d\n", (int)data->roi_cfg.TopLeftX, (int)data->roi_cfg.TopLeftY, (int)data->roi_cfg.BotRightX, (int)data->roi_cfg.BotRightY);
+		} else {
+			vl53lx_errmsg("wrong roi syntax %s ", buf);
+			rc = -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 = 0;
+
+	if (data->enable_sensor) {
+		vl53lx_errmsg("can't change distance mode while ranging\n");
+		rc = -EBUSY;
+	} else {
+		switch (distance_mode) {
+		case VL53LX_DISTANCEMODE_SHORT:
+		case VL53LX_DISTANCEMODE_MEDIUM:
+		case VL53LX_DISTANCEMODE_LONG:
+			data->distance_mode = distance_mode;
+			break;
+		default:
+			vl53lx_errmsg("invalid distance mode %d\n",
+				distance_mode);
+			rc = -EINVAL;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+IMPLEMENT_PARAMETER_INTEGER(distance_mode, "distance mode")
+
+static DEVICE_ATTR(distance_mode, 0660, stmvl53lx_show_distance_mode, stmvl53lx_store_distance_mode);
+
+static int stmvl53lx_set_crosstalk_enable(struct stmvl53lx_data *data,
+	int crosstalk_enable)
+{
+	int rc = 0;
+
+	if (data->enable_sensor) {
+		vl53lx_errmsg("can't change crosstalk enable while ranging\n");
+		rc = -EBUSY;
+	} else if (crosstalk_enable == 0 || crosstalk_enable == 1) {
+		data->crosstalk_enable = crosstalk_enable;
+	} else {
+		vl53lx_errmsg("invalid crosstalk enable %d\n",
+			crosstalk_enable);
+		rc = -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 = 0;
+
+	if (force_device_on_en != 0 && force_device_on_en != 1) {
+		vl53lx_errmsg("invalid force_device_on_en mode %d\n",
+			force_device_on_en);
+		return -EINVAL;
+	}
+
+	data->force_device_on_en = 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 = reset_release(data);
+	else
+		rc = 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_device_on_en, stmvl53lx_store_force_device_on_en);
+
+static int stmvl53lx_set_offset_correction_mode(struct stmvl53lx_data *data,
+	int offset_correction_mode)
+{
+	int rc = 0;
+
+	if (data->enable_sensor) {
+		vl53lx_errmsg(
+			"can't change offset correction mode while ranging\n");
+		rc = -EBUSY;
+	} else {
+		switch (offset_correction_mode) {
+		case VL53LX_OFFSETCORRECTIONMODE_STANDARD:
+		case VL53LX_OFFSETCORRECTIONMODE_PERVCSEL:
+			data->offset_correction_mode = offset_correction_mode;
+			break;
+		default:
+			vl53lx_errmsg("invalid offset correction mode %d\n",
+				offset_correction_mode);
+			rc = -EINVAL;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+IMPLEMENT_PARAMETER_INTEGER(offset_correction_mode, "offset correction mode")
+
+static DEVICE_ATTR(offset_correction_mode, 0660, stmvl53lx_show_offset_correction_mode, stmvl53lx_store_offset_correction_mode);
+
+static ssize_t stmvl53lx_do_flush(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct stmvl53lx_data *data = dev_get_drvdata(dev);
+
+	mutex_lock(&data->work_mutex);
+
+	data->flush_todo_counter++;
+	if (data->enable_sensor == 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 device_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 device_attribute *attr, const char *buf, size_t count)
+{
+	int enable_debug;
+	int rc = 0;
+
+	if (kstrtoint(buf, 0, &enable_debug)) {
+		vl53lx_errmsg("invalid syntax in %s", buf);
+		rc = -EINVAL;
+	} else
+		stmvl53lx_enable_debug = enable_debug;
+
+	return rc ? rc : count;
+}
+
+static DEVICE_ATTR(enable_debug, 0660, stmvl53lx_show_enable_debug, stmvl53lx_store_enable_debug);
+
+static ssize_t stmvl53lx_show_last_error_config(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct stmvl53lx_data *data = 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, NULL);
+
+static ssize_t display_FixPoint1616(char *buf, size_t size, FixPoint1616_t fix)
+{
+	uint32_t msb = fix >> 16;
+	uint32_t lsb = fix & 0xffff;
+
+	lsb = (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, struct device_attribute *attr, char *buf)
+{
+	struct stmvl53lx_data *data = dev_get_drvdata(dev);
+	ssize_t res = 0;
+
+	res += display_FixPoint1616(&buf[res], PAGE_SIZE - res, data->optical_offset_x);
+	res += scnprintf(&buf[res], PAGE_SIZE - res, " ");
+	res += display_FixPoint1616(&buf[res], PAGE_SIZE - res, data->optical_offset_y);
+	res += scnprintf(&buf[res], PAGE_SIZE - res, "\n");
+	return res;
+}
+
+static DEVICE_ATTR(optical_center, 0440, stmvl53lx_show_optical_center_config, NULL);
+
+VL53LX_Error VL53LX_set_tuning_parm(VL53LX_DEV Dev, VL53LX_TuningParms tuning_parm_key, int32_t tuning_parm_value)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
+	VL53LX_xtalkextract_config_t *pXC = &(pdev->xtalk_extract_cfg);
+
+	switch (tuning_parm_key) {
+	case VL53LX_TUNINGPARM_VERSION:
+		pdev->tuning_parms.tp_tuning_parm_version = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_KEY_TABLE_VERSION:
+		pdev->tuning_parms.tp_tuning_parm_key_table_version = (uint16_t)tuning_parm_value;
+		if ((uint16_t)tuning_parm_value != VL53LX_TUNINGPARM_KEY_TABLE_VERSION_DEFAULT)
+			status = VL53LX_ERROR_TUNING_PARM_KEY_MISMATCH;
+		break;
+	case VL53LX_TUNINGPARM_LLD_VERSION:
+		pdev->tuning_parms.tp_tuning_parm_lld_version = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_ALGO_SELECT:
+		pHP->hist_algo_select = (VL53LX_HistAlgoSelect)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_TARGET_ORDER:
+		pHP->hist_target_order = (VL53LX_HistTargetOrder)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_FILTER_WOI_0:
+		pHP->filter_woi0 = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_FILTER_WOI_1:
+		pHP->filter_woi1 = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD:
+		pHP->hist_amb_est_method = (VL53LX_HistAmbEstMethod)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0:
+		pHP->ambient_thresh_sigma0 = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1:
+		pHP->ambient_thresh_sigma1 = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS:
+		pHP->min_ambient_thresh_events = (int32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER:
+		pHP->ambient_thresh_events_scaler = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD:
+		pHP->noise_threshold = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT:
+		pHP->signal_total_events_limit = (int32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM:
+		pHP->sigma_estimator__sigma_ref_mm = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM:
+		pHP->sigma_thresh = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_GAIN_FACTOR:
+		pdev->gain_cal.histogram_ranging_gain_factor = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE:
+		pHP->algo__consistency_check__phase_tolerance = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM:
+		pHP->algo__consistency_check__min_max_tolerance = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA:
+		pHP->algo__consistency_check__event_sigma = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT:
+		pHP->algo__consistency_check__event_min_spad_count = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE:
+		pdev->tuning_parms.tp_init_phase_rtn_hist_long = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE:
+		pdev->tuning_parms.tp_init_phase_rtn_hist_med = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE:
+		pdev->tuning_parms.tp_init_phase_rtn_hist_short = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE:
+		pdev->tuning_parms.tp_init_phase_ref_hist_long = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE:
+		pdev->tuning_parms.tp_init_phase_ref_hist_med = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE:
+		pdev->tuning_parms.tp_init_phase_ref_hist_short = (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 = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM:
+		pdev->xtalk_cfg.algo__crosstalk_detect_max_valid_range_mm = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM:
+		pdev->xtalk_cfg.algo__crosstalk_detect_max_sigma_mm = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE:
+		pHP->algo__crosstalk_detect_min_max_tolerance = (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 = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA:
+		pHP->algo__crosstalk_detect_event_sigma = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS:
+		pdev->xtalk_cfg.histogram_mode_crosstalk_margin_kcps = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE:
+		pdev->tuning_parms.tp_consistency_lite_phase_tolerance = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_PHASECAL_TARGET:
+		pdev->tuning_parms.tp_phasecal_target = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE:
+		pdev->tuning_parms.tp_cal_repeat_rate = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR:
+		pdev->gain_cal.standard_ranging_gain_factor = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM:
+		pdev->tuning_parms.tp_lite_min_clip = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM:
+		pdev->tuning_parms.tp_lite_long_sigma_thresh_mm = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM:
+		pdev->tuning_parms.tp_lite_med_sigma_thresh_mm = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM:
+		pdev->tuning_parms.tp_lite_short_sigma_thresh_mm = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS:
+		pdev->tuning_parms.tp_lite_long_min_count_rate_rtn_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS:
+		pdev->tuning_parms.tp_lite_med_min_count_rate_rtn_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS:
+		pdev->tuning_parms.tp_lite_short_min_count_rate_rtn_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH:
+		pdev->tuning_parms.tp_lite_sigma_est_pulse_width_ns = (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 = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM:
+		pdev->tuning_parms.tp_lite_sigma_ref_mm = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_RIT_MULT:
+		pdev->xtalk_cfg.crosstalk_range_ignore_threshold_mult = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_SEED_CONFIG:
+		pdev->tuning_parms.tp_lite_seed_cfg = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_QUANTIFIER:
+		pdev->tuning_parms.tp_lite_quantifier = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT:
+		pdev->tuning_parms.tp_lite_first_order_select = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS:
+		pdev->xtalk_cfg.lite_mode_crosstalk_margin_kcps = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE:
+		pdev->tuning_parms.tp_init_phase_rtn_lite_long = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE:
+		pdev->tuning_parms.tp_init_phase_rtn_lite_med = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE:
+		pdev->tuning_parms.tp_init_phase_rtn_lite_short = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE:
+		pdev->tuning_parms.tp_init_phase_ref_lite_long = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE:
+		pdev->tuning_parms.tp_init_phase_ref_lite_med = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE:
+		pdev->tuning_parms.tp_init_phase_ref_lite_short = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_TIMED_SEED_CONFIG:
+		pdev->tuning_parms.tp_timed_seed_cfg = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA:
+		pdev->dmax_cfg.signal_thresh_sigma = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0:
+		pdev->dmax_cfg.target_reflectance_for_dmax_calc[0] = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1:
+		pdev->dmax_cfg.target_reflectance_for_dmax_calc[1] = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2:
+		pdev->dmax_cfg.target_reflectance_for_dmax_calc[2] = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3:
+		pdev->dmax_cfg.target_reflectance_for_dmax_calc[3] = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4:
+		pdev->dmax_cfg.target_reflectance_for_dmax_calc[4] = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_VHV_LOOPBOUND:
+		pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE:
+		pdev->refspadchar.device_test_mode = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD:
+		pdev->refspadchar.VL53LX_p_005 = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US:
+		pdev->refspadchar.timeout_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS:
+		pdev->refspadchar.target_count_rate_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS:
+		pdev->refspadchar.min_count_rate_limit_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS:
+		pdev->refspadchar.max_count_rate_limit_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES:
+		pXC->num_of_samples = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM:
+		pXC->algo__crosstalk_extract_min_valid_range_mm = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM:
+		pXC->algo__crosstalk_extract_max_valid_range_mm = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS:
+		pXC->dss_config__target_total_rate_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US:
+		pXC->phasecal_config_timeout_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS:
+		 pXC->algo__crosstalk_extract_max_valid_rate_kcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_SIGMA_THRESHOLD_MM:
+		pXC->algo__crosstalk_extract_max_sigma_mm = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US:
+		pXC->mm_config_timeout_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US:
+		pXC->range_config_timeout_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS:
+		pdev->offsetcal_cfg.dss_config__target_total_rate_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US:
+		pdev->offsetcal_cfg.phasecal_config_timeout_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US:
+		pdev->offsetcal_cfg.mm_config_timeout_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US:
+		pdev->offsetcal_cfg.range_config_timeout_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES:
+		pdev->offsetcal_cfg.pre_num_of_samples = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES:
+		pdev->offsetcal_cfg.mm1_num_of_samples = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES:
+		pdev->offsetcal_cfg.mm2_num_of_samples = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS:
+		pdev->zonecal_cfg.dss_config__target_total_rate_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US:
+		pdev->zonecal_cfg.phasecal_config_timeout_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US:
+		pdev->zonecal_cfg.mm_config_timeout_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES:
+		pdev->zonecal_cfg.phasecal_num_of_samples = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US:
+		pdev->zonecal_cfg.range_config_timeout_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES:
+		pdev->zonecal_cfg.zone_num_of_samples = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD:
+		pdev->ssc_cfg.VL53LX_p_005 = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_SPADMAP_VCSEL_START:
+		pdev->ssc_cfg.vcsel_start = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS:
+		pdev->ssc_cfg.rate_limit_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
+		pdev->tuning_parms.tp_dss_target_lite_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
+		pdev->tuning_parms.tp_dss_target_histo_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
+		pdev->tuning_parms.tp_dss_target_histo_mz_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS:
+		pdev->tuning_parms.tp_dss_target_timed_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_phasecal_timeout_lite_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_phasecal_timeout_hist_long_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_phasecal_timeout_hist_med_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_phasecal_timeout_hist_short_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_phasecal_timeout_mz_long_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_phasecal_timeout_mz_med_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_phasecal_timeout_mz_short_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_phasecal_timeout_timed_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_mm_timeout_lite_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_mm_timeout_histo_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_mm_timeout_mz_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_mm_timeout_timed_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_range_timeout_lite_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_range_timeout_histo_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_range_timeout_mz_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_range_timeout_timed_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN:
+		pdev->smudge_correct_config.smudge_margin = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN:
+		pdev->smudge_correct_config.noise_margin = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT:
+		pdev->smudge_correct_config.user_xtalk_offset_limit = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI:
+		pdev->smudge_correct_config.user_xtalk_offset_limit_hi = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT:
+		pdev->smudge_correct_config.sample_limit = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA:
+		pdev->smudge_correct_config.single_xtalk_delta = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA:
+		pdev->smudge_correct_config.averaged_xtalk_delta = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT:
+		pdev->smudge_correct_config.smudge_corr_clip_limit = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_SCALER_CALC_METHOD:
+		pdev->smudge_correct_config.scaler_calc_method = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER:
+		pdev->smudge_correct_config.x_gradient_scaler = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER:
+		pdev->smudge_correct_config.y_gradient_scaler = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET:
+		pdev->smudge_correct_config.user_scaler_set = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY:
+		pdev->smudge_correct_config.smudge_corr_single_apply = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD:
+		pdev->smudge_correct_config.smudge_corr_ambient_threshold = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS:
+		pdev->smudge_correct_config.nodetect_ambient_threshold = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT:
+		pdev->smudge_correct_config.nodetect_sample_limit = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS:
+		pdev->smudge_correct_config.nodetect_xtalk_offset = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM:
+		pdev->smudge_correct_config.nodetect_min_range_mm = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND:
+		pdev->low_power_auto_data.vhv_loop_bound = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_mm_timeout_lpa_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US:
+		pdev->tuning_parms.tp_range_timeout_lpa_us = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS:
+		pdev->tuning_parms.tp_dss_target_very_short_mcps = (uint16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER:
+		pdev->tuning_parms.tp_phasecal_patch_power = (uint16_t) tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_MERGE:
+		pdev->tuning_parms.tp_hist_merge = (uint16_t) tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD:
+		pdev->tuning_parms.tp_reset_merge_threshold = (uint16_t) tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE:
+		pdev->tuning_parms.tp_hist_merge_max_size = (uint16_t) tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR:
+		pdev->smudge_correct_config.max_smudge_factor = (uint32_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_ENABLE:
+		pdev->tuning_parms.tp_uwr_enable = (uint8_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MIN:
+		pdev->tuning_parms.tp_uwr_med_z_1_min = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MAX:
+		pdev->tuning_parms.tp_uwr_med_z_1_max = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MIN:
+		pdev->tuning_parms.tp_uwr_med_z_2_min = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MAX:
+		pdev->tuning_parms.tp_uwr_med_z_2_max = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MIN:
+		pdev->tuning_parms.tp_uwr_med_z_3_min = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MAX:
+		pdev->tuning_parms.tp_uwr_med_z_3_max = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MIN:
+		pdev->tuning_parms.tp_uwr_med_z_4_min = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MAX:
+		pdev->tuning_parms.tp_uwr_med_z_4_max = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MIN:
+		pdev->tuning_parms.tp_uwr_med_z_5_min = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MAX:
+		pdev->tuning_parms.tp_uwr_med_z_5_max = (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 = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEB:
+		pdev->tuning_parms.tp_uwr_med_corr_z_1_rangeb = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEA:
+		pdev->tuning_parms.tp_uwr_med_corr_z_2_rangea = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEB:
+		pdev->tuning_parms.tp_uwr_med_corr_z_2_rangeb = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEA:
+		pdev->tuning_parms.tp_uwr_med_corr_z_3_rangea = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEB:
+		pdev->tuning_parms.tp_uwr_med_corr_z_3_rangeb = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEA:
+		pdev->tuning_parms.tp_uwr_med_corr_z_4_rangea = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEB:
+		pdev->tuning_parms.tp_uwr_med_corr_z_4_rangeb = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEA:
+		pdev->tuning_parms.tp_uwr_med_corr_z_5_rangea = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEB:
+		pdev->tuning_parms.tp_uwr_med_corr_z_5_rangeb = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MIN:
+		pdev->tuning_parms.tp_uwr_lng_z_1_min = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MAX:
+		pdev->tuning_parms.tp_uwr_lng_z_1_max = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MIN:
+		pdev->tuning_parms.tp_uwr_lng_z_2_min = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MAX:
+		pdev->tuning_parms.tp_uwr_lng_z_2_max = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MIN:
+		pdev->tuning_parms.tp_uwr_lng_z_3_min = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MAX:
+		pdev->tuning_parms.tp_uwr_lng_z_3_max = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MIN:
+		pdev->tuning_parms.tp_uwr_lng_z_4_min = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MAX:
+		pdev->tuning_parms.tp_uwr_lng_z_4_max = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MIN:
+		pdev->tuning_parms.tp_uwr_lng_z_5_min = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MAX:
+		pdev->tuning_parms.tp_uwr_lng_z_5_max = (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 = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEB:
+		pdev->tuning_parms.tp_uwr_lng_corr_z_1_rangeb = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEA:
+		pdev->tuning_parms.tp_uwr_lng_corr_z_2_rangea = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEB:
+		pdev->tuning_parms.tp_uwr_lng_corr_z_2_rangeb = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEA:
+		pdev->tuning_parms.tp_uwr_lng_corr_z_3_rangea = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEB:
+		pdev->tuning_parms.tp_uwr_lng_corr_z_3_rangeb = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEA:
+		pdev->tuning_parms.tp_uwr_lng_corr_z_4_rangea = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEB:
+		pdev->tuning_parms.tp_uwr_lng_corr_z_4_rangeb = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEA:
+		pdev->tuning_parms.tp_uwr_lng_corr_z_5_rangea = (int16_t)tuning_parm_value;
+		break;
+	case VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEB:
+		pdev->tuning_parms.tp_uwr_lng_corr_z_5_rangeb = (int16_t)tuning_parm_value;
+		break;
+	default:
+		status = VL53LX_ERROR_INVALID_PARAMS;
+		break;
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_SetTuningParameter(VL53LX_DEV Dev, uint16_t TuningParameterId, int32_t TuningParameterValue)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+
+	if (TuningParameterId == VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS)
+		return VL53LX_ERROR_INVALID_PARAMS;
+
+	if (TuningParameterId >= 32768)
+		Status = VL53LX_set_tuning_parm(Dev, TuningParameterId, TuningParameterValue);
+	else {
+		if (TuningParameterId < VL53LX_TUNING_MAX_TUNABLE_KEY)
+			BDTable[TuningParameterId] = TuningParameterValue;
+		else
+			Status = VL53LX_ERROR_INVALID_PARAMS;
+	}
+
+	return Status;
+}
+
+static int stmvl53lx_set_tuning(struct stmvl53lx_data *data, int key, int value)
+{
+	int rc = 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 = VL53LX_SetTuningParameter(&data->stdev, key, value);
+	if (rc)
+		rc = store_last_error(data, rc);
+
+	return rc;
+}
+
+static ssize_t stmvl53lx_store_tuning(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct stmvl53lx_data *data = dev_get_drvdata(dev);
+	int key;
+	int value;
+	int n;
+	int rc = 0;
+
+	mutex_lock(&data->work_mutex);
+
+	n = sscanf(buf, "%d %d", &key, &value);
+	if (n != 2) {
+		rc = -EINVAL;
+		goto error;
+	}
+	rc = 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 TuningParameterId, int32_t *pTuningParameterValue)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+
+	if (TuningParameterId >= 32768)
+		Status = VL53LX_get_tuning_parm(Dev, TuningParameterId, pTuningParameterValue);
+	else {
+		if (TuningParameterId < VL53LX_TUNING_MAX_TUNABLE_KEY)
+			*pTuningParameterValue = BDTable[TuningParameterId];
+		else
+			Status = VL53LX_ERROR_INVALID_PARAMS;
+	}
+
+	return Status;
+}
+
+static int stmvl53lx_display_tuning_key(struct stmvl53lx_data *data, char *buf, int *pos, int key)
+{
+	int rc = 0;
+	int value = 0;
+	int sz;
+
+	rc = VL53LX_GetTuningParameter(&data->stdev, key, &value);
+	if (rc)
+		return 0;
+
+	sz = snprintf(&buf[*pos], PAGE_SIZE - *pos, "%d %d\n", key, value);
+	if (sz >= PAGE_SIZE - *pos)
+		return -ENOSPC;
+
+	*pos += sz;
+
+	return 0;
+}
+
+static ssize_t stmvl53lx_show_tuning_status(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	const int max_tuning_key = 65535;
+	struct stmvl53lx_data *data = dev_get_drvdata(dev);
+	int rc = 0;
+	int i;
+	int pos = 0;
+
+	mutex_lock(&data->work_mutex);
+
+	for (i = 0; i < max_tuning_key; ++i) {
+		rc = 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 *data,
+	int smudge_correction_mode)
+{
+	int rc = 0;
+
+	if (data->enable_sensor) {
+		vl53lx_errmsg("can't change smudge corr mode while ranging\n");
+		rc = -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 = smudge_correction_mode;
+			break;
+		default:
+			vl53lx_errmsg("invalid smudge correction mode %d\n",
+				smudge_correction_mode);
+			rc = -EINVAL;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+IMPLEMENT_PARAMETER_INTEGER(smudge_correction_mode, "smudge correction mode")
+
+static DEVICE_ATTR(smudge_correction_mode, 0660, stmvl53lx_show_smudge_correction_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 = dev_get_drvdata(dev);
+	int param;
+
+	mutex_lock(&data->work_mutex);
+	param = 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_value_changed_config, NULL);
+
+static struct attribute *stmvl53lx_attributes[] = {
+	&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 = {
+	.attrs = stmvl53lx_attributes,
+};
+
+static int ctrl_param_last_error(struct stmvl53lx_data *data, struct stmvl53lx_parameter *param)
+{
+	int rc = 0;
+
+	if (param->is_read) {
+		param->value = data->last_error;
+		param->status = 0;
+		vl53lx_dbgmsg("get last error %d", param->value);
+		rc = 0;
+	} else {
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+static int ctrl_param_optical_center(struct stmvl53lx_data *data, struct stmvl53lx_parameter *param)
+{
+	if (!param->is_read)
+		return -EINVAL;
+
+	param->value = data->optical_offset_x;
+	param->value2 = 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 = 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 = -ENODEV;
+		goto done;
+	}
+	rc = copy_from_user(&param, p, sizeof(param));
+	param.status = 0;
+	if (rc) {
+		rc = -EFAULT;
+		goto done;
+	}
+	switch (param.name) {
+	case VL53LX_POLLDELAY_PAR:
+		rc = ctrl_param_poll_delay_ms(data, &param);
+		break;
+	case VL53LX_TIMINGBUDGET_PAR:
+		rc = ctrl_param_timing_budget(data, &param);
+		break;
+	case VL53LX_DISTANCEMODE_PAR:
+		rc = ctrl_param_distance_mode(data, &param);
+	break;
+	case VL53LX_XTALKENABLE_PAR:
+		rc = ctrl_param_crosstalk_enable(data, &param);
+	break;
+	case VL53LX_FORCEDEVICEONEN_PAR:
+		rc = ctrl_param_force_device_on_en(data, &param);
+	break;
+	case VL53LX_LASTERROR_PAR:
+		rc = ctrl_param_last_error(data, &param);
+	break;
+	case VL53LX_OFFSETCORRECTIONMODE_PAR:
+		rc = ctrl_param_offset_correction_mode(data, &param);
+	break;
+	case VL53LX_OPTICALCENTER_PAR:
+		rc = ctrl_param_optical_center(data, &param);
+	break;
+	case VL53LX_TUNING_PAR:
+		rc = ctrl_param_tuning(data, &param);
+		break;
+	case VL53LX_SMUDGECORRECTIONMODE_PAR:
+		rc = ctrl_param_smudge_correction_mode(data, &param);
+	break;
+	case VL53LX_ISXTALKVALUECHANGED_PAR:
+		rc = ctrl_param_is_xtalk_value_changed(data, &param);
+	break;
+	default:
+		vl53lx_errmsg("unknown or unsupported %d\n", param.name);
+		rc = -EINVAL;
+	}
+
+	if (param.is_read  && rc == 0) {
+		rc2 = copy_to_user(p, &param, sizeof(param));
+		if (rc2) {
+			rc = -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_calibration_data_t *pcal_data)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
+	VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
+	VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
+	uint32_t tempu32;
+
+	if (pcal_data->struct_version != VL53LX_LL_CALIBRATION_DATA_STRUCT_VERSION) {
+		status = VL53LX_ERROR_INVALID_PARAMS;
+	}
+
+	if (status == 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(VL53LX_dmax_calibration_data_t));
+		memcpy(&(pdev->xtalk_shapes), &(pcal_data->xtalkhisto), sizeof(VL53LX_xtalk_histogram_data_t));
+		memcpy(&(pdev->gain_cal), &(pcal_data->gain_cal), sizeof(VL53LX_gain_calibration_data_t));
+		memcpy(&(pdev->cal_peak_rate_map), &(pcal_data->cal_peak_rate_map), sizeof(VL53LX_cal_peak_rate_map_t));
+		memcpy(&(pdev->per_vcsel_cal_data), &(pcal_data->per_vcsel_cal_data), sizeof(VL53LX_per_vcsel_period_offset_cal_data_t));
+
+		pC->algo__crosstalk_compensation_plane_offset_kcps = pN->algo__crosstalk_compensation_plane_offset_kcps;
+		pC->algo__crosstalk_compensation_x_plane_gradient_kcps = pN->algo__crosstalk_compensation_x_plane_gradient_kcps;
+		pC->algo__crosstalk_compensation_y_plane_gradient_kcps = pN->algo__crosstalk_compensation_y_plane_gradient_kcps;
+
+		pHP->algo__crosstalk_compensation_plane_offset_kcps = VL53LX_calc_crosstalk_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 = pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
+		pHP->algo__crosstalk_compensation_y_plane_gradient_kcps = pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
+
+		if (pC->global_crosstalk_compensation_enable == 0x00) {
+			pN->algo__crosstalk_compensation_plane_offset_kcps = 0x00;
+			pN->algo__crosstalk_compensation_x_plane_gradient_kcps = 0x00;
+			pN->algo__crosstalk_compensation_y_plane_gradient_kcps = 0x00;
+		} else {
+			tempu32 = VL53LX_calc_crosstalk_plane_offset_with_margin(pC->algo__crosstalk_compensation_plane_offset_kcps, pC->lite_mode_crosstalk_margin_kcps);
+			if (tempu32 > 0xFFFF)
+				tempu32 = 0xFFFF;
+
+			pN->algo__crosstalk_compensation_plane_offset_kcps = (uint16_t)tempu32;
+		}
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_get_current_xtalk_settings(VL53LX_DEV Dev, VL53LX_xtalk_calibration_results_t *pxtalk)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	uint8_t i;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pxtalk->algo__crosstalk_compensation_plane_offset_kcps = pdev->xtalk_cfg.algo__crosstalk_compensation_plane_offset_kcps;
+	pxtalk->algo__crosstalk_compensation_x_plane_gradient_kcps = pdev->xtalk_cfg.algo__crosstalk_compensation_x_plane_gradient_kcps;
+	pxtalk->algo__crosstalk_compensation_y_plane_gradient_kcps = pdev->xtalk_cfg.algo__crosstalk_compensation_y_plane_gradient_kcps;
+	for (i = 0; i < VL53LX_BIN_REC_SIZE; i++)
+		pxtalk->algo__xtalk_cpo_HistoMerge_kcps[i] = pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[i];
+
+	return status;
+}
+
+VL53LX_Error VL53LX_set_current_xtalk_settings(VL53LX_DEV Dev, VL53LX_xtalk_calibration_results_t *pxtalk)
+{
+	uint8_t i;
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->xtalk_cfg.algo__crosstalk_compensation_plane_offset_kcps = pxtalk->algo__crosstalk_compensation_plane_offset_kcps;
+	pdev->xtalk_cfg.algo__crosstalk_compensation_x_plane_gradient_kcps = pxtalk->algo__crosstalk_compensation_x_plane_gradient_kcps;
+	pdev->xtalk_cfg.algo__crosstalk_compensation_y_plane_gradient_kcps = pxtalk->algo__crosstalk_compensation_y_plane_gradient_kcps;
+	for (i = 0; i < VL53LX_BIN_REC_SIZE; i++)
+		pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[i] = pxtalk->algo__xtalk_cpo_HistoMerge_kcps[i];
+
+	return status;
+}
+
+VL53LX_Error VL53LX_SetCalibrationData(VL53LX_DEV Dev, VL53LX_CalibrationData_t *pCalibrationData)
+{
+	VL53LX_Error Status = 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 = pCalibrationData->struct_version - VL53LX_ADDITIONAL_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), sizeof(VL53LX_optical_centre_t));
+	memcpy(&(cal_data.xtalkhisto), &(pCalibrationData->xtalkhisto), sizeof(VL53LX_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_map), 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 = &pCalibrationData->customer;
+	x = pC->algo__crosstalk_compensation_plane_offset_kcps;
+	cal_data.customer.algo__crosstalk_compensation_plane_offset_kcps = (uint16_t)(x&0x0000FFFF);
+
+	cal_data.customer.global_config__spad_enables_ref_0 = pC->global_config__spad_enables_ref_0;
+	cal_data.customer.global_config__spad_enables_ref_1 = pC->global_config__spad_enables_ref_1;
+	cal_data.customer.global_config__spad_enables_ref_2 = pC->global_config__spad_enables_ref_2;
+	cal_data.customer.global_config__spad_enables_ref_3 = pC->global_config__spad_enables_ref_3;
+	cal_data.customer.global_config__spad_enables_ref_4 = pC->global_config__spad_enables_ref_4;
+	cal_data.customer.global_config__spad_enables_ref_5 = pC->global_config__spad_enables_ref_5;
+	cal_data.customer.global_config__ref_en_start_select = pC->global_config__ref_en_start_select;
+	cal_data.customer.ref_spad_man__num_requested_ref_spads = pC->ref_spad_man__num_requested_ref_spads;
+	cal_data.customer.ref_spad_man__ref_location = pC->ref_spad_man__ref_location;
+	cal_data.customer.algo__crosstalk_compensation_x_plane_gradient_kcps = pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
+	cal_data.customer.algo__crosstalk_compensation_y_plane_gradient_kcps = pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
+	cal_data.customer.ref_spad_char__total_rate_target_mcps = pC->ref_spad_char__total_rate_target_mcps;
+	cal_data.customer.algo__part_to_part_range_offset_mm = pC->algo__part_to_part_range_offset_mm;
+	cal_data.customer.mm_config__inner_offset_mm = pC->mm_config__inner_offset_mm;
+	cal_data.customer.mm_config__outer_offset_mm = pC->mm_config__outer_offset_mm;
+
+	Status = VL53LX_set_part_to_part_data(Dev, &cal_data);
+
+	if (Status != VL53LX_ERROR_NONE)
+		goto ENDFUNC;
+
+	Status = VL53LX_get_current_xtalk_settings(Dev, &xtalk);
+
+	if (Status != VL53LX_ERROR_NONE)
+		goto ENDFUNC;
+
+	xtalk.algo__crosstalk_compensation_plane_offset_kcps = x;
+
+	Status = VL53LX_set_tuning_parm(Dev, VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS, x);
+
+	memcpy(&(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]), &(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]), sizeof(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps));
+
+	Status = VL53LX_set_current_xtalk_settings(Dev, &xtalk);
+
+ENDFUNC:
+	return Status;
+
+}
+
+VL53LX_Error VL53LX_get_part_to_part_data(VL53LX_DEV Dev, VL53LX_calibration_data_t *pcal_data)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
+	VL53LX_customer_nvm_managed_t *pCN = &(pcal_data->customer);
+
+	pcal_data->struct_version = 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 = 0xFFFF;
+	} else {
+		pCN->algo__crosstalk_compensation_plane_offset_kcps = (uint16_t)pC->algo__crosstalk_compensation_plane_offset_kcps;
+	}
+	pCN->algo__crosstalk_compensation_x_plane_gradient_kcps = pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
+	pCN->algo__crosstalk_compensation_y_plane_gradient_kcps = pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
+
+	memcpy(&(pcal_data->fmt_dmax_cal), &(pdev->fmt_dmax_cal), sizeof(VL53LX_dmax_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(VL53LX_optical_centre_t));
+	memcpy(&(pcal_data->xtalkhisto), &(pdev->xtalk_shapes), sizeof(VL53LX_xtalk_histogram_data_t));
+	memcpy(&(pcal_data->gain_cal), &(pdev->gain_cal), sizeof(VL53LX_gain_calibration_data_t));
+	memcpy(&(pcal_data->cal_peak_rate_map), &(pdev->cal_peak_rate_map), sizeof(VL53LX_cal_peak_rate_map_t));
+	memcpy(&(pcal_data->per_vcsel_cal_data), &(pdev->per_vcsel_cal_data), sizeof(VL53LX_per_vcsel_period_offset_cal_data_t));
+
+	return status;
+}
+
+VL53LX_Error VL53LX_GetCalibrationData(VL53LX_DEV Dev, VL53LX_CalibrationData_t *pCalibrationData)
+{
+	VL53LX_Error Status = 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 = VL53LX_get_part_to_part_data(Dev, &cal_data);
+
+	pCalibrationData->struct_version = cal_data.struct_version + VL53LX_ADDITIONAL_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), sizeof(VL53LX_optical_centre_t));
+	memcpy(&(pCalibrationData->xtalkhisto), &(cal_data.xtalkhisto), sizeof(VL53LX_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_map), 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 = &pCalibrationData->customer;
+	pC2 = &cal_data.customer;
+	pC->global_config__spad_enables_ref_0 = pC2->global_config__spad_enables_ref_0;
+	pC->global_config__spad_enables_ref_1 = pC2->global_config__spad_enables_ref_1;
+	pC->global_config__spad_enables_ref_2 = pC2->global_config__spad_enables_ref_2;
+	pC->global_config__spad_enables_ref_3 = pC2->global_config__spad_enables_ref_3;
+	pC->global_config__spad_enables_ref_4 = pC2->global_config__spad_enables_ref_4;
+	pC->global_config__spad_enables_ref_5 = pC2->global_config__spad_enables_ref_5;
+	pC->global_config__ref_en_start_select = pC2->global_config__ref_en_start_select;
+	pC->ref_spad_man__num_requested_ref_spads = pC2->ref_spad_man__num_requested_ref_spads;
+	pC->ref_spad_man__ref_location = pC2->ref_spad_man__ref_location;
+	pC->algo__crosstalk_compensation_x_plane_gradient_kcps = pC2->algo__crosstalk_compensation_x_plane_gradient_kcps;
+	pC->algo__crosstalk_compensation_y_plane_gradient_kcps = pC2->algo__crosstalk_compensation_y_plane_gradient_kcps;
+	pC->ref_spad_char__total_rate_target_mcps = pC2->ref_spad_char__total_rate_target_mcps;
+	pC->algo__part_to_part_range_offset_mm = pC2->algo__part_to_part_range_offset_mm;
+	pC->mm_config__inner_offset_mm = pC2->mm_config__inner_offset_mm;
+	pC->mm_config__outer_offset_mm = pC2->mm_config__outer_offset_mm;
+
+	pC->algo__crosstalk_compensation_plane_offset_kcps = (uint32_t)(pC2->algo__crosstalk_compensation_plane_offset_kcps);
+
+	Status = VL53LX_get_current_xtalk_settings(Dev, &xtalk);
+
+	if (Status != VL53LX_ERROR_NONE)
+		goto ENDFUNC;
+
+	tmp = xtalk.algo__crosstalk_compensation_plane_offset_kcps;
+	pC->algo__crosstalk_compensation_plane_offset_kcps = tmp;
+	tmp = xtalk.algo__crosstalk_compensation_x_plane_gradient_kcps;
+	pC->algo__crosstalk_compensation_x_plane_gradient_kcps = tmp;
+	tmp = xtalk.algo__crosstalk_compensation_y_plane_gradient_kcps;
+	pC->algo__crosstalk_compensation_y_plane_gradient_kcps = tmp;
+
+	memcpy(&(pCalibrationData->algo__xtalk_cpo_HistoMerge_kcps[0]), &(xtalk.algo__xtalk_cpo_HistoMerge_kcps[0]), sizeof(pCalibrationData->algo__xtalk_cpo_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 count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct stmvl53lx_data *data = dev_get_drvdata(dev);
+	VL53LX_CalibrationData_t calib;
+	int rc = 0;
+	void *src = (void *) &calib;
+
+	mutex_lock(&data->work_mutex);
+
+	vl53lx_dbgmsg("off = %lld / count = %d", off, count);
+
+	if (off < 0 || off > sizeof(VL53LX_CalibrationData_t))
+		goto invalid;
+
+	memset(&calib, 0, sizeof(calib));
+	rc = VL53LX_GetCalibrationData(&data->stdev, &calib);
+	if (rc) {
+		vl53lx_errmsg("VL53LX_GetCalibrationData fail %d", rc);
+		rc = store_last_error(data, rc);
+		goto error;
+	}
+
+	if (off + count > sizeof(VL53LX_CalibrationData_t))
+		count = sizeof(VL53LX_CalibrationData_t) - off;
+	memcpy(buf, src + off, count);
+
+	mutex_unlock(&data->work_mutex);
+	return count;
+
+invalid:
+	vl53lx_errmsg("invalid syntax");
+	rc = -EINVAL;
+	goto error;
+
+error:
+	mutex_unlock(&data->work_mutex);
+	return rc;
+}
+
+static ssize_t stmvl53lx_calib_data_write(struct file *filp, struct kobject *kobj, const struct bin_attribute *attr, char *buf, loff_t off, size_t count)
+{
+	int rc = 0;
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct stmvl53lx_data *data = dev_get_drvdata(dev);
+
+	mutex_lock(&data->work_mutex);
+
+	vl53lx_dbgmsg("off = %lld / count = %d", off, count);
+
+	if (data->enable_sensor) {
+		rc = -EBUSY;
+		vl53lx_errmsg("can't set calib data while ranging\n");
+		goto error;
+	}
+
+	if (off != 0 || count != sizeof(VL53LX_CalibrationData_t))
+		goto invalid;
+
+	rc = VL53LX_SetCalibrationData(&data->stdev, (VL53LX_CalibrationData_t *) buf);
+	if (rc) {
+		vl53lx_errmsg("VL53LX_SetCalibrationData fail %d", rc);
+		rc = store_last_error(data, rc);
+		goto error;
+	}
+
+	mutex_unlock(&data->work_mutex);
+	return count;
+
+invalid:
+	vl53lx_errmsg("invalid syntax");
+	rc = -EINVAL;
+	goto error;
+
+error:
+	mutex_unlock(&data->work_mutex);
+
+	return rc;
+}
+
+static struct bin_attribute stmvl53lx_calib_data_attr = {
+	.attr = {
+		.name = "calibration_data",
+		.mode = 0660,
+	},
+	.size = sizeof(VL53LX_CalibrationData_t),
+	.read = stmvl53lx_calib_data_read,
+	.write = stmvl53lx_calib_data_write,
+};
+
+void VL53LX_init_version(VL53LX_DEV Dev)
+{
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->version.ll_major    = VL53LX_LL_API_IMPLEMENTATION_VER_MAJOR;
+	pdev->version.ll_minor    = VL53LX_LL_API_IMPLEMENTATION_VER_MINOR;
+	pdev->version.ll_build    = VL53LX_LL_API_IMPLEMENTATION_VER_SUB;
+	pdev->version.ll_revision = VL53LX_LL_API_IMPLEMENTATION_VER_REVISION;
+}
+
+VL53LX_Error VL53LX_get_static_nvm_managed(VL53LX_DEV Dev, VL53LX_static_nvm_managed_t *pdata)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint8_t comms_buffer[VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES];
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_ReadMulti(Dev, VL53LX_I2C_SLAVE__DEVICE_ADDRESS, comms_buffer, VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_i2c_decode_static_nvm_managed(VL53LX_STATIC_NVM_MANAGED_I2C_SIZE_BYTES, comms_buffer, pdata);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_i2c_decode_customer_nvm_managed(uint16_t buf_size, uint8_t *pbuffer, VL53LX_customer_nvm_managed_t *pdata)
+{
+	VL53LX_Error status = 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 = (*(pbuffer +   0));
+	pdata->global_config__spad_enables_ref_1 = (*(pbuffer +   1));
+	pdata->global_config__spad_enables_ref_2 = (*(pbuffer +   2));
+	pdata->global_config__spad_enables_ref_3 = (*(pbuffer +   3));
+	pdata->global_config__spad_enables_ref_4 = (*(pbuffer +   4));
+	pdata->global_config__spad_enables_ref_5 = (*(pbuffer +   5)) & 0xF;
+	pdata->global_config__ref_en_start_select = (*(pbuffer +   6));
+	pdata->ref_spad_man__num_requested_ref_spads = (*(pbuffer +   7)) & 0x3F;
+	pdata->ref_spad_man__ref_location = (*(pbuffer +   8)) & 0x3;
+	pdata->algo__crosstalk_compensation_plane_offset_kcps = (VL53LX_i2c_decode_uint16_t(2, pbuffer +   9));
+	pdata->algo__crosstalk_compensation_x_plane_gradient_kcps = (VL53LX_i2c_decode_int16_t(2, pbuffer +  11));
+	pdata->algo__crosstalk_compensation_y_plane_gradient_kcps = (VL53LX_i2c_decode_int16_t(2, pbuffer +  13));
+	pdata->ref_spad_char__total_rate_target_mcps = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  15));
+	pdata->algo__part_to_part_range_offset_mm = (VL53LX_i2c_decode_int16_t(2, pbuffer +  17)) & 0x1FFF;
+	pdata->mm_config__inner_offset_mm = (VL53LX_i2c_decode_int16_t(2, pbuffer +  19));
+	pdata->mm_config__outer_offset_mm = (VL53LX_i2c_decode_int16_t(2, pbuffer +  21));
+
+	return status;
+}
+
+VL53LX_Error VL53LX_get_customer_nvm_managed(VL53LX_DEV Dev, VL53LX_customer_nvm_managed_t *pdata)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint8_t comms_buffer[VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES];
+	int16_t offset;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_ReadMulti(Dev, VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0, comms_buffer, VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_i2c_decode_customer_nvm_managed(VL53LX_CUSTOMER_NVM_MANAGED_I2C_SIZE_BYTES, comms_buffer, pdata);
+
+	if (status == VL53LX_ERROR_NONE) {
+		offset = pdata->algo__part_to_part_range_offset_mm;
+		offset = offset / 4;
+		if (offset >= 1024)
+			offset -= 2048;
+		pdata->algo__part_to_part_range_offset_mm = 0;
+		pdata->mm_config__inner_offset_mm = offset;
+		pdata->mm_config__outer_offset_mm = offset;
+	}
+
+	return status;
+}
+
+VL53LX_Error VL53LX_i2c_decode_nvm_copy_data(uint16_t buf_size, uint8_t *pbuffer, VL53LX_nvm_copy_data_t *pdata)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (buf_size < VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES)
+		return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
+
+	pdata->identification__model_id = (*(pbuffer +   0));
+	pdata->identification__module_type = (*(pbuffer +   1));
+	pdata->identification__revision_id = (*(pbuffer +   2));
+	pdata->identification__module_id = (VL53LX_i2c_decode_uint16_t(2, pbuffer +   3));
+	pdata->ana_config__fast_osc__trim_max = (*(pbuffer +   5)) & 0x7F;
+	pdata->ana_config__fast_osc__freq_set = (*(pbuffer +   6)) & 0x7;
+	pdata->ana_config__vcsel_trim = (*(pbuffer +   7)) & 0x7;
+	pdata->ana_config__vcsel_selion = (*(pbuffer +   8)) & 0x3F;
+	pdata->ana_config__vcsel_selion_max = (*(pbuffer +   9)) & 0x3F;
+	pdata->protected_laser_safety__lock_bit = (*(pbuffer +  10)) & 0x1;
+	pdata->laser_safety__key = (*(pbuffer +  11)) & 0x7F;
+	pdata->laser_safety__key_ro = (*(pbuffer +  12)) & 0x1;
+	pdata->laser_safety__clip = (*(pbuffer +  13)) & 0x3F;
+	pdata->laser_safety__mult = (*(pbuffer +  14)) & 0x3F;
+	pdata->global_config__spad_enables_rtn_0 = (*(pbuffer +  15));
+	pdata->global_config__spad_enables_rtn_1 = (*(pbuffer +  16));
+	pdata->global_config__spad_enables_rtn_2 = (*(pbuffer +  17));
+	pdata->global_config__spad_enables_rtn_3 = (*(pbuffer +  18));
+	pdata->global_config__spad_enables_rtn_4 = (*(pbuffer +  19));
+	pdata->global_config__spad_enables_rtn_5 = (*(pbuffer +  20));
+	pdata->global_config__spad_enables_rtn_6 = (*(pbuffer +  21));
+	pdata->global_config__spad_enables_rtn_7 = (*(pbuffer +  22));
+	pdata->global_config__spad_enables_rtn_8 = (*(pbuffer +  23));
+	pdata->global_config__spad_enables_rtn_9 = (*(pbuffer +  24));
+	pdata->global_config__spad_enables_rtn_10 = (*(pbuffer +  25));
+	pdata->global_config__spad_enables_rtn_11 = (*(pbuffer +  26));
+	pdata->global_config__spad_enables_rtn_12 = (*(pbuffer +  27));
+	pdata->global_config__spad_enables_rtn_13 = (*(pbuffer +  28));
+	pdata->global_config__spad_enables_rtn_14 = (*(pbuffer +  29));
+	pdata->global_config__spad_enables_rtn_15 = (*(pbuffer +  30));
+	pdata->global_config__spad_enables_rtn_16 = (*(pbuffer +  31));
+	pdata->global_config__spad_enables_rtn_17 = (*(pbuffer +  32));
+	pdata->global_config__spad_enables_rtn_18 = (*(pbuffer +  33));
+	pdata->global_config__spad_enables_rtn_19 = (*(pbuffer +  34));
+	pdata->global_config__spad_enables_rtn_20 = (*(pbuffer +  35));
+	pdata->global_config__spad_enables_rtn_21 = (*(pbuffer +  36));
+	pdata->global_config__spad_enables_rtn_22 = (*(pbuffer +  37));
+	pdata->global_config__spad_enables_rtn_23 = (*(pbuffer +  38));
+	pdata->global_config__spad_enables_rtn_24 = (*(pbuffer +  39));
+	pdata->global_config__spad_enables_rtn_25 = (*(pbuffer +  40));
+	pdata->global_config__spad_enables_rtn_26 = (*(pbuffer +  41));
+	pdata->global_config__spad_enables_rtn_27 = (*(pbuffer +  42));
+	pdata->global_config__spad_enables_rtn_28 = (*(pbuffer +  43));
+	pdata->global_config__spad_enables_rtn_29 = (*(pbuffer +  44));
+	pdata->global_config__spad_enables_rtn_30 = (*(pbuffer +  45));
+	pdata->global_config__spad_enables_rtn_31 = (*(pbuffer +  46));
+	pdata->roi_config__mode_roi_centre_spad = (*(pbuffer +  47));
+	pdata->roi_config__mode_roi_xy_size = (*(pbuffer +  48));
+
+	return status;
+}
+
+VL53LX_Error VL53LX_get_nvm_copy_data(VL53LX_DEV Dev, VL53LX_nvm_copy_data_t *pdata)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint8_t comms_buffer[VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES];
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_ReadMulti(Dev, VL53LX_IDENTIFICATION__MODEL_ID, comms_buffer, VL53LX_NVM_COPY_DATA_I2C_SIZE_BYTES);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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, uint8_t *pbuffer)
+{
+	*(pbuffer +  0) = pdata->global_config__spad_enables_rtn_0;
+	*(pbuffer +  1) = pdata->global_config__spad_enables_rtn_1;
+	*(pbuffer +  2) = pdata->global_config__spad_enables_rtn_2;
+	*(pbuffer +  3) = pdata->global_config__spad_enables_rtn_3;
+	*(pbuffer +  4) = pdata->global_config__spad_enables_rtn_4;
+	*(pbuffer +  5) = pdata->global_config__spad_enables_rtn_5;
+	*(pbuffer +  6) = pdata->global_config__spad_enables_rtn_6;
+	*(pbuffer +  7) = pdata->global_config__spad_enables_rtn_7;
+	*(pbuffer +  8) = pdata->global_config__spad_enables_rtn_8;
+	*(pbuffer +  9) = pdata->global_config__spad_enables_rtn_9;
+	*(pbuffer + 10) = pdata->global_config__spad_enables_rtn_10;
+	*(pbuffer + 11) = pdata->global_config__spad_enables_rtn_11;
+	*(pbuffer + 12) = pdata->global_config__spad_enables_rtn_12;
+	*(pbuffer + 13) = pdata->global_config__spad_enables_rtn_13;
+	*(pbuffer + 14) = pdata->global_config__spad_enables_rtn_14;
+	*(pbuffer + 15) = pdata->global_config__spad_enables_rtn_15;
+	*(pbuffer + 16) = pdata->global_config__spad_enables_rtn_16;
+	*(pbuffer + 17) = pdata->global_config__spad_enables_rtn_17;
+	*(pbuffer + 18) = pdata->global_config__spad_enables_rtn_18;
+	*(pbuffer + 19) = pdata->global_config__spad_enables_rtn_19;
+	*(pbuffer + 20) = pdata->global_config__spad_enables_rtn_20;
+	*(pbuffer + 21) = pdata->global_config__spad_enables_rtn_21;
+	*(pbuffer + 22) = pdata->global_config__spad_enables_rtn_22;
+	*(pbuffer + 23) = pdata->global_config__spad_enables_rtn_23;
+	*(pbuffer + 24) = pdata->global_config__spad_enables_rtn_24;
+	*(pbuffer + 25) = pdata->global_config__spad_enables_rtn_25;
+	*(pbuffer + 26) = pdata->global_config__spad_enables_rtn_26;
+	*(pbuffer + 27) = pdata->global_config__spad_enables_rtn_27;
+	*(pbuffer + 28) = pdata->global_config__spad_enables_rtn_28;
+	*(pbuffer + 29) = pdata->global_config__spad_enables_rtn_29;
+	*(pbuffer + 30) = pdata->global_config__spad_enables_rtn_30;
+	*(pbuffer + 31) = pdata->global_config__spad_enables_rtn_31;
+}
+
+VL53LX_Error VL53LX_set_firmware_enable_register(VL53LX_DEV Dev, uint8_t value)
+{
+	VL53LX_Error status         = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->sys_ctrl.firmware__enable = value;
+
+	status = VL53LX_WrByte(Dev, VL53LX_FIRMWARE__ENABLE, pdev->sys_ctrl.firmware__enable);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_disable_firmware(VL53LX_DEV Dev)
+{
+	VL53LX_Error status       = VL53LX_ERROR_NONE;
+
+	status = VL53LX_set_firmware_enable_register(Dev, 0x00);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_nvm_enable(VL53LX_DEV Dev, uint16_t nvm_ctrl_pulse_width, int32_t nvm_power_up_delay_us)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_disable_firmware(Dev);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_enable_powerforce(Dev);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WaitUs(Dev, VL53LX_ENABLE_POWERFORCE_SETTLING_TIME_US);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__PDN, 0x01);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__CLK_CTRL1, 0x05);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WaitUs(Dev, nvm_power_up_delay_us);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__MODE, 0x01);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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   = VL53LX_ERROR_NONE;
+	uint8_t      nvm_addr = 0;
+
+	for (nvm_addr = start_address;
+		nvm_addr < (start_address+count) ; nvm_addr++) {
+
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__ADDR, nvm_addr);
+
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__READN, 0x00);
+
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_WaitUs(Dev, VL53LX_NVM_READ_TRIGGER_DELAY_US);
+
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__READN, 0x01);
+
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_ReadMulti(Dev, VL53LX_RANGING_CORE__NVM_CTRL__DATAOUT_MMM, pdata, 4);
+
+		pdata = pdata + 4;
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_enable_firmware(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	status = VL53LX_set_firmware_enable_register(Dev, 0x01);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_nvm_disable(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__READN, 0x01);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_RANGING_CORE__NVM_CTRL__PDN, 0x00);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_disable_powerforce(Dev);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_enable_firmware(Dev);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_read_nvm_raw_data(VL53LX_DEV Dev, uint8_t start_address, uint8_t count, uint8_t *pnvm_raw_data)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_nvm_enable(Dev, 0x0004, VL53LX_NVM_POWER_UP_DELAY_US);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_nvm_read(Dev, start_address, count, pnvm_raw_data);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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   = VL53LX_ERROR_NONE;
+	uint16_t  tmp = 0;
+
+	if (buf_size < VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE)
+		return VL53LX_ERROR_BUFFER_TOO_SMALL;
+
+	tmp  = 0x0100;
+	tmp -= (uint16_t)*(pbuffer + 2);
+	if (tmp > 0x0FF)
+		tmp = 0;
+
+	pdata->x_centre = (uint8_t)tmp;
+	pdata->y_centre = *(pbuffer + 3);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_read_nvm_optical_centre(VL53LX_DEV Dev, VL53LX_optical_centre_t *pcentre)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint8_t nvm_data[VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE];
+
+	status = VL53LX_read_nvm_raw_data(Dev, (uint8_t)(VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_INDEX >> 2), (uint8_t)(VL53LX_NVM__FMT__OPTICAL_CENTRE_DATA_SIZE >> 2), nvm_data);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_nvm_decode_optical_centre(VL53LX_NVM__FMT__OPTICAL_CENTRE_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   = VL53LX_ERROR_NONE;
+
+	uint8_t   *ptmp = NULL;
+	uint8_t       i = 0;
+
+	if (buf_size < VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE)
+		return VL53LX_ERROR_BUFFER_TOO_SMALL;
+
+	pdata->cal_distance_mm = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer);
+
+	pdata->cal_reflectance_pc = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 2);
+	pdata->cal_reflectance_pc = pdata->cal_reflectance_pc >> 6;
+
+	pdata->max_samples = VL53LX_NVM_PEAK_RATE_MAP_SAMPLES;
+	pdata->width       = VL53LX_NVM_PEAK_RATE_MAP_WIDTH;
+	pdata->height      = VL53LX_NVM_PEAK_RATE_MAP_HEIGHT;
+
+	ptmp = pbuffer + 4;
+	for (i = 0 ; i < VL53LX_NVM_PEAK_RATE_MAP_SAMPLES ; i++) {
+		pdata->peak_rate_mcps[i] = (uint16_t)VL53LX_i2c_decode_uint16_t(2, ptmp);
+		ptmp += 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 = VL53LX_ERROR_NONE;
+	uint8_t nvm_data[VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE];
+
+	status = VL53LX_read_nvm_raw_data(Dev, (uint8_t)(VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_INDEX >> 2), (uint8_t)(VL53LX_NVM__FMT__CAL_PEAK_RATE_MAP_DATA_SIZE >> 2), nvm_data);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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_size, uint8_t *pbuffer, VL53LX_additional_offset_cal_data_t *pdata)
+{
+	VL53LX_Error status   = 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 = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer);
+	pdata->result__mm_outer_actual_effective_spads = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 2);
+	pdata->result__mm_inner_peak_signal_count_rtn_mcps = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 4);
+	pdata->result__mm_outer_peak_signal_count_rtn_mcps = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 6);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_read_nvm_additional_offset_cal_data(VL53LX_DEV Dev, VL53LX_additional_offset_cal_data_t *pcal_data)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	uint8_t nvm_data[VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE];
+
+	status = VL53LX_read_nvm_raw_data(Dev, (uint8_t)(VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_INDEX >> 2), (uint8_t)(VL53LX_NVM__FMT__ADDITIONAL_OFFSET_CAL_DATA_SIZE >> 2), nvm_data);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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 *pbyte_index, uint8_t *pbit_index, uint8_t *pbit_mask)
+{
+	*pbyte_index  = spad_number >> 3;
+	*pbit_index   = spad_number & 0x07;
+	*pbit_mask    = 0x01 << *pbit_index;
+}
+
+uint8_t VL53LX_is_aperture_location(uint8_t row, uint8_t col)
+{
+	uint8_t is_aperture = 0;
+	uint8_t mod_row     = row % 4;
+	uint8_t mod_col     = col % 4;
+
+	if (mod_row == 0 && mod_col == 2)
+		is_aperture = 1;
+
+	if (mod_row == 2 && mod_col == 0)
+		is_aperture = 1;
+
+	return is_aperture;
+}
+
+void VL53LX_decode_row_col(uint8_t spad_number, uint8_t *prow, uint8_t *pcol)
+{
+	if (spad_number > 127) {
+		*prow = 8 + ((255-spad_number) & 0x07);
+		*pcol = (spad_number-128) >> 3;
+	} else {
+		*prow = spad_number & 0x07;
+		*pcol = (127-spad_number) >> 3;
+	}
+}
+
+void VL53LX_decode_zone_size(uint8_t encoded_xy_size, uint8_t *pwidth, uint8_t *pheight)
+{
+	*pheight = encoded_xy_size >> 4;
+	*pwidth  = 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 = 0;
+	uint8_t y_centre = 0;
+	uint8_t width    = 0;
+	uint8_t height   = 0;
+
+	VL53LX_decode_row_col(encoded_xy_centre, &y_centre, &x_centre);
+	VL53LX_decode_zone_size(encoded_xy_size, &width, &height);
+
+	*px_ll = (int16_t)x_centre - ((int16_t)width + 1) / 2;
+	if (*px_ll < 0)
+		*px_ll = 0;
+
+	*px_ur = *px_ll + (int16_t)width;
+	if (*px_ur > (VL53LX_SPAD_ARRAY_WIDTH-1))
+		*px_ur = VL53LX_SPAD_ARRAY_WIDTH-1;
+
+	*py_ll = (int16_t)y_centre - ((int16_t)height + 1) / 2;
+	if (*py_ll < 0)
+		*py_ll = 0;
+
+	*py_ur = *py_ll + (int16_t)height;
+	if (*py_ur > (VL53LX_SPAD_ARRAY_HEIGHT-1))
+		*py_ur = 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         = 0;
+	int16_t   y         = 0;
+	int16_t   mm_x_ll   = 0;
+	int16_t   mm_y_ll   = 0;
+	int16_t   mm_x_ur   = 0;
+	int16_t   mm_y_ur   = 0;
+	int16_t   zone_x_ll = 0;
+	int16_t   zone_y_ll = 0;
+	int16_t   zone_x_ur = 0;
+	int16_t   zone_y_ur = 0;
+	uint8_t   spad_number = 0;
+	uint8_t   byte_index  = 0;
+	uint8_t   bit_index   = 0;
+	uint8_t   bit_mask    = 0;
+
+	uint8_t   is_aperture = 0;
+	uint16_t  spad_attenuation = 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 = 0;
+	*pmm_outer_effective_spads = 0;
+
+	for (y = zone_y_ll; y <= zone_y_ur; y++) {
+		for (x = zone_x_ll; x <= 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_index, &bit_mask);
+			if ((pgood_spads[byte_index] & bit_mask) > 0) {
+				is_aperture = VL53LX_is_aperture_location((uint8_t)y, (uint8_t)x);
+				if (is_aperture > 0)
+					spad_attenuation = aperture_attenuation;
+				else
+					spad_attenuation = 0x0100;
+				if (x >= mm_x_ll && x <= mm_x_ur && y >= mm_y_ll && y <= mm_y_ur)
+					*pmm_inner_effective_spads += spad_attenuation;
+				else
+					*pmm_outer_effective_spads += spad_attenuation;
+			}
+		}
+	}
+}
+
+VL53LX_Error VL53LX_nvm_decode_fmt_range_results_data(uint16_t buf_size, uint8_t *pbuffer, VL53LX_decoded_nvm_fmt_range_data_t *pdata)
+{
+	VL53LX_Error status   = 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 = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer);
+	pdata->ref_spad_array__num_requested_ref_spads = *(pbuffer+2);
+	pdata->ref_spad_array__ref_location = *(pbuffer+3);
+	pdata->result__peak_signal_count_rate_rtn_mcps = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 4);
+	pdata->result__ambient_count_rate_rtn_mcps = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 6);
+	pdata->result__peak_signal_count_rate_ref_mcps = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 8);
+	pdata->result__ambient_count_rate_ref_mcps = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 10);
+	pdata->measured_distance_mm = (uint16_t)VL53LX_i2c_decode_uint16_t(2, pbuffer + 12);
+	pdata->measured_distance_stdev_mm = (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 = VL53LX_ERROR_NONE;
+	uint8_t nvm_data[VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES];
+
+	status = 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 == VL53LX_ERROR_NONE)
+		status = VL53LX_nvm_decode_fmt_range_results_data(VL53LX_NVM__FMT__RANGE_RESULTS__SIZE_BYTES, nvm_data, prange_data);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_get_mode_mitigation_roi(VL53LX_DEV Dev, VL53LX_user_zone_t *pmm_roi)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	uint8_t  x       = 0;
+	uint8_t  y       = 0;
+	uint8_t  xy_size = 0;
+
+	VL53LX_decode_row_col(pdev->nvm_copy_data.roi_config__mode_roi_centre_spad, &y, &x);
+
+	pmm_roi->x_centre = x;
+	pmm_roi->y_centre = y;
+
+	xy_size = pdev->nvm_copy_data.roi_config__mode_roi_xy_size;
+
+	pmm_roi->height = xy_size >> 4;
+	pmm_roi->width  = xy_size & 0x0F;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_read_p2p_data(VL53LX_DEV Dev)
+{
+	VL53LX_Error status       = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
+	VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
+	VL53LX_additional_offset_cal_data_t *pCD = &(pdev->add_off_cal_data);
+	VL53LX_decoded_nvm_fmt_range_data_t fmt_rrd;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_get_static_nvm_managed(Dev, &(pdev->stat_nvm));
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_get_customer_nvm_managed(Dev, &(pdev->customer));
+
+	if (status == VL53LX_ERROR_NONE) {
+		status = VL53LX_get_nvm_copy_data(Dev, &(pdev->nvm_copy_data));
+
+		if (status == VL53LX_ERROR_NONE)
+			VL53LX_copy_rtn_good_spads_to_buffer(&(pdev->nvm_copy_data), &(pdev->rtn_good_spads[0]));
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+		pHP->algo__crosstalk_compensation_plane_offset_kcps =
+		pN->algo__crosstalk_compensation_plane_offset_kcps;
+		pHP->algo__crosstalk_compensation_x_plane_gradient_kcps =
+		pN->algo__crosstalk_compensation_x_plane_gradient_kcps;
+		pHP->algo__crosstalk_compensation_y_plane_gradient_kcps =
+		pN->algo__crosstalk_compensation_y_plane_gradient_kcps;
+	}
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_read_nvm_optical_centre(Dev, &(pdev->optical_centre));
+
+
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_read_nvm_cal_peak_rate_map(Dev, &(pdev->cal_peak_rate_map));
+
+	if (status == VL53LX_ERROR_NONE) {
+		status = VL53LX_read_nvm_additional_offset_cal_data(Dev, &(pdev->add_off_cal_data));
+
+		if (pCD->result__mm_inner_peak_signal_count_rtn_mcps == 0 && pCD->result__mm_outer_peak_signal_count_rtn_mcps == 0) {
+			pCD->result__mm_inner_peak_signal_count_rtn_mcps = 0x0080;
+			pCD->result__mm_outer_peak_signal_count_rtn_mcps = 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_effective_spads));
+		}
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+
+		status = VL53LX_read_nvm_fmt_range_results_data(Dev, VL53LX_NVM__FMT__RANGE_RESULTS__140MM_DARK, &fmt_rrd);
+		if (status == VL53LX_ERROR_NONE) {
+			pdev->fmt_dmax_cal.ref__actual_effective_spads = fmt_rrd.result__actual_effective_rtn_spads;
+			pdev->fmt_dmax_cal.ref__peak_signal_count_rate_mcps = fmt_rrd.result__peak_signal_count_rate_rtn_mcps;
+			pdev->fmt_dmax_cal.ref__distance_mm = fmt_rrd.measured_distance_mm;
+
+			if (pdev->cal_peak_rate_map.cal_reflectance_pc != 0) {
+				pdev->fmt_dmax_cal.ref_reflectance_pc = pdev->cal_peak_rate_map.cal_reflectance_pc;
+			} else {
+				pdev->fmt_dmax_cal.ref_reflectance_pc = 0x0014;
+			}
+			pdev->fmt_dmax_cal.coverglass_transmission = 0x0100;
+		}
+	}
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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 = 0xBCCC;
+	}
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_get_mode_mitigation_roi(Dev, &(pdev->mm_roi));
+
+	if (pdev->optical_centre.x_centre == 0 && pdev->optical_centre.y_centre == 0) {
+		pdev->optical_centre.x_centre = pdev->mm_roi.x_centre << 4;
+		pdev->optical_centre.y_centre = pdev->mm_roi.y_centre << 4;
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_init_refspadchar_config_struct(VL53LX_refspadchar_config_t *pdata)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	pdata->device_test_mode          = VL53LX_TUNINGPARM_REFSPADCHAR_DEVICE_TEST_MODE_DEFAULT;
+	pdata->VL53LX_p_005              = VL53LX_TUNINGPARM_REFSPADCHAR_VCSEL_PERIOD_DEFAULT;
+	pdata->timeout_us                = VL53LX_TUNINGPARM_REFSPADCHAR_PHASECAL_TIMEOUT_US_DEFAULT;
+	pdata->target_count_rate_mcps    = VL53LX_TUNINGPARM_REFSPADCHAR_TARGET_COUNT_RATE_MCPS_DEFAULT;
+	pdata->min_count_rate_limit_mcps = VL53LX_TUNINGPARM_REFSPADCHAR_MIN_COUNTRATE_LIMIT_MCPS_DEFAULT;
+	pdata->max_count_rate_limit_mcps = VL53LX_TUNINGPARM_REFSPADCHAR_MAX_COUNTRATE_LIMIT_MCPS_DEFAULT;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_init_ssc_config_struct(VL53LX_ssc_config_t *pdata)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	pdata->array_select = VL53LX_DEVICESSCARRAY_RTN;
+	pdata->VL53LX_p_005 = VL53LX_TUNINGPARM_SPADMAP_VCSEL_PERIOD_DEFAULT;
+	pdata->vcsel_start  = VL53LX_TUNINGPARM_SPADMAP_VCSEL_START_DEFAULT;
+	pdata->vcsel_width = 0x02;
+	pdata->timeout_us   = 36000;
+	pdata->rate_limit_mcps = VL53LX_TUNINGPARM_SPADMAP_RATE_LIMIT_MCPS_DEFAULT;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_init_xtalk_config_struct(VL53LX_customer_nvm_managed_t *pnvm, VL53LX_xtalk_config_t *pdata)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	pdata->algo__crosstalk_compensation_plane_offset_kcps      = pnvm->algo__crosstalk_compensation_plane_offset_kcps;
+	pdata->algo__crosstalk_compensation_x_plane_gradient_kcps  = pnvm->algo__crosstalk_compensation_x_plane_gradient_kcps;
+	pdata->algo__crosstalk_compensation_y_plane_gradient_kcps  = pnvm->algo__crosstalk_compensation_y_plane_gradient_kcps;
+
+	pdata->nvm_default__crosstalk_compensation_plane_offset_kcps      = (uint32_t)pnvm->algo__crosstalk_compensation_plane_offset_kcps;
+	pdata->nvm_default__crosstalk_compensation_x_plane_gradient_kcps  = pnvm->algo__crosstalk_compensation_x_plane_gradient_kcps;
+	pdata->nvm_default__crosstalk_compensation_y_plane_gradient_kcps  = pnvm->algo__crosstalk_compensation_y_plane_gradient_kcps;
+
+	pdata->histogram_mode_crosstalk_margin_kcps                = VL53LX_TUNINGPARM_HIST_XTALK_MARGIN_KCPS_DEFAULT;
+	pdata->lite_mode_crosstalk_margin_kcps                     = VL53LX_TUNINGPARM_LITE_XTALK_MARGIN_KCPS_DEFAULT;
+
+	pdata->crosstalk_range_ignore_threshold_mult = VL53LX_TUNINGPARM_LITE_RIT_MULT_DEFAULT;
+
+	if ((pdata->algo__crosstalk_compensation_plane_offset_kcps == 0x00) && (pdata->algo__crosstalk_compensation_x_plane_gradient_kcps == 0x00) && (pdata->algo__crosstalk_compensation_y_plane_gradient_kcps == 0x00))
+		pdata->global_crosstalk_compensation_enable = 0x00;
+	else
+		pdata->global_crosstalk_compensation_enable = 0x01;
+
+	if ((status == VL53LX_ERROR_NONE) && (pdata->global_crosstalk_compensation_enable == 0x01)) {
+		pdata->crosstalk_range_ignore_threshold_rate_mcps = VL53LX_calc_range_ignore_threshold(pdata->algo__crosstalk_compensation_plane_offset_kcps, pdata->algo__crosstalk_compensation_x_plane_gradient_kcps, pdata->algo__crosstalk_compensation_y_plane_gradient_kcps, pdata->crosstalk_range_ignore_threshold_mult);
+	} else {
+		pdata->crosstalk_range_ignore_threshold_rate_mcps = 0;
+	}
+
+	pdata->algo__crosstalk_detect_min_valid_range_mm  = VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM_DEFAULT;
+	pdata->algo__crosstalk_detect_max_valid_range_mm  = VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM_DEFAULT;
+	pdata->algo__crosstalk_detect_max_valid_rate_kcps = VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS_DEFAULT;
+	pdata->algo__crosstalk_detect_max_sigma_mm        = VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM_DEFAULT;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_init_xtalk_extract_config_struct(VL53LX_xtalkextract_config_t *pdata)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	pdata->dss_config__target_total_rate_mcps          = VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_RATE_MCPS_DEFAULT;
+	pdata->mm_config_timeout_us                        = VL53LX_TUNINGPARM_XTALK_EXTRACT_DSS_TIMEOUT_US_DEFAULT;
+	pdata->num_of_samples                              = VL53LX_TUNINGPARM_XTALK_EXTRACT_NUM_OF_SAMPLES_DEFAULT;
+	pdata->phasecal_config_timeout_us                  = VL53LX_TUNINGPARM_XTALK_EXTRACT_PHASECAL_TIMEOUT_US_DEFAULT;
+	pdata->range_config_timeout_us                     = VL53LX_TUNINGPARM_XTALK_EXTRACT_BIN_TIMEOUT_US_DEFAULT;
+	pdata->algo__crosstalk_extract_min_valid_range_mm  = VL53LX_TUNINGPARM_XTALK_EXTRACT_MIN_FILTER_THRESH_MM_DEFAULT;
+	pdata->algo__crosstalk_extract_max_valid_range_mm  = VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_FILTER_THRESH_MM_DEFAULT;
+	pdata->algo__crosstalk_extract_max_valid_rate_kcps = VL53LX_TUNINGPARM_XTALK_EXTRACT_MAX_VALID_RATE_KCPS_DEFAULT;
+	pdata->algo__crosstalk_extract_max_sigma_mm        = 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 = VL53LX_ERROR_NONE;
+
+	pdata->dss_config__target_total_rate_mcps          = VL53LX_TUNINGPARM_OFFSET_CAL_DSS_RATE_MCPS_DEFAULT;
+	pdata->phasecal_config_timeout_us                  = VL53LX_TUNINGPARM_OFFSET_CAL_PHASECAL_TIMEOUT_US_DEFAULT;
+	pdata->range_config_timeout_us                     = VL53LX_TUNINGPARM_OFFSET_CAL_RANGE_TIMEOUT_US_DEFAULT;
+	pdata->mm_config_timeout_us                        = VL53LX_TUNINGPARM_OFFSET_CAL_MM_TIMEOUT_US_DEFAULT;
+	pdata->pre_num_of_samples                          = VL53LX_TUNINGPARM_OFFSET_CAL_PRE_SAMPLES_DEFAULT;
+	pdata->mm1_num_of_samples                          = VL53LX_TUNINGPARM_OFFSET_CAL_MM1_SAMPLES_DEFAULT;
+	pdata->mm2_num_of_samples                          = VL53LX_TUNINGPARM_OFFSET_CAL_MM2_SAMPLES_DEFAULT;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_init_zone_cal_config_struct(VL53LX_zonecal_config_t *pdata)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	pdata->dss_config__target_total_rate_mcps          = VL53LX_TUNINGPARM_ZONE_CAL_DSS_RATE_MCPS_DEFAULT;
+	pdata->phasecal_config_timeout_us                  = VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_TIMEOUT_US_DEFAULT;
+	pdata->range_config_timeout_us                     = VL53LX_TUNINGPARM_ZONE_CAL_RANGE_TIMEOUT_US_DEFAULT;
+	pdata->mm_config_timeout_us                        = VL53LX_TUNINGPARM_ZONE_CAL_DSS_TIMEOUT_US_DEFAULT;
+	pdata->phasecal_num_of_samples                     = VL53LX_TUNINGPARM_ZONE_CAL_PHASECAL_NUM_SAMPLES_DEFAULT;
+	pdata->zone_num_of_samples                         = VL53LX_TUNINGPARM_ZONE_CAL_ZONE_NUM_SAMPLES_DEFAULT;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_init_hist_post_process_config_struct(uint8_t xtalk_compensation_enable, VL53LX_hist_post_process_config_t *pdata)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	pdata->hist_algo_select = VL53LX_TUNINGPARM_HIST_ALGO_SELECT_DEFAULT;
+	pdata->hist_target_order = VL53LX_TUNINGPARM_HIST_TARGET_ORDER_DEFAULT;
+
+	pdata->filter_woi0                   = VL53LX_TUNINGPARM_HIST_FILTER_WOI_0_DEFAULT;
+	pdata->filter_woi1                   = VL53LX_TUNINGPARM_HIST_FILTER_WOI_1_DEFAULT;
+
+	pdata->hist_amb_est_method = VL53LX_TUNINGPARM_HIST_AMB_EST_METHOD_DEFAULT;
+
+	pdata->ambient_thresh_sigma0         = VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_0_DEFAULT;
+	pdata->ambient_thresh_sigma1         = VL53LX_TUNINGPARM_HIST_AMB_THRESH_SIGMA_1_DEFAULT;
+
+	pdata->ambient_thresh_events_scaler     = VL53LX_TUNINGPARM_HIST_AMB_EVENTS_SCALER_DEFAULT;
+
+	pdata->min_ambient_thresh_events     = VL53LX_TUNINGPARM_HIST_MIN_AMB_THRESH_EVENTS_DEFAULT;
+
+	pdata->noise_threshold               = VL53LX_TUNINGPARM_HIST_NOISE_THRESHOLD_DEFAULT;
+
+	pdata->signal_total_events_limit     = VL53LX_TUNINGPARM_HIST_SIGNAL_TOTAL_EVENTS_LIMIT_DEFAULT;
+	pdata->sigma_estimator__sigma_ref_mm = VL53LX_TUNINGPARM_HIST_SIGMA_EST_REF_MM_DEFAULT;
+
+	pdata->sigma_thresh                  = VL53LX_TUNINGPARM_HIST_SIGMA_THRESH_MM_DEFAULT;
+	pdata->range_offset_mm            =      0;
+	pdata->gain_factor                = VL53LX_TUNINGPARM_HIST_GAIN_FACTOR_DEFAULT;
+
+	pdata->valid_phase_low = 0x08;
+	pdata->valid_phase_high = 0x88;
+
+	pdata->algo__consistency_check__phase_tolerance = VL53LX_TUNINGPARM_CONSISTENCY_HIST_PHASE_TOLERANCE_DEFAULT;
+	pdata->algo__consistency_check__event_sigma = VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_DEFAULT;
+	pdata->algo__consistency_check__event_min_spad_count = VL53LX_TUNINGPARM_CONSISTENCY_HIST_EVENT_SIGMA_MIN_SPAD_LIMIT_DEFAULT;
+	pdata->algo__consistency_check__min_max_tolerance = VL53LX_TUNINGPARM_CONSISTENCY_HIST_MIN_MAX_TOLERANCE_MM_DEFAULT;
+	pdata->algo__crosstalk_compensation_enable = xtalk_compensation_enable;
+	pdata->algo__crosstalk_detect_min_valid_range_mm  = VL53LX_TUNINGPARM_XTALK_DETECT_MIN_VALID_RANGE_MM_DEFAULT;
+	pdata->algo__crosstalk_detect_max_valid_range_mm  = VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RANGE_MM_DEFAULT;
+	pdata->algo__crosstalk_detect_max_valid_rate_kcps = VL53LX_TUNINGPARM_XTALK_DETECT_MAX_VALID_RATE_KCPS_DEFAULT;
+	pdata->algo__crosstalk_detect_max_sigma_mm        = VL53LX_TUNINGPARM_XTALK_DETECT_MAX_SIGMA_MM_DEFAULT;
+
+	pdata->algo__crosstalk_detect_event_sigma       = VL53LX_TUNINGPARM_XTALK_DETECT_EVENT_SIGMA_DEFAULT;
+
+	pdata->algo__crosstalk_detect_min_max_tolerance   = VL53LX_TUNINGPARM_XTALK_DETECT_MIN_MAX_TOLERANCE_DEFAULT;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_init_hist_gen3_dmax_config_struct(VL53LX_hist_gen3_dmax_config_t *pdata)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	pdata->dss_config__target_total_rate_mcps = 0x1400;
+	pdata->dss_config__aperture_attenuation = 0x38;
+
+	pdata->signal_thresh_sigma                 = VL53LX_TUNINGPARM_DMAX_CFG_SIGNAL_THRESH_SIGMA_DEFAULT;
+	pdata->ambient_thresh_sigma = 0x70;
+	pdata->min_ambient_thresh_events           = 16;
+	pdata->signal_total_events_limit           = 100;
+	pdata->max_effective_spads = 0xFFFF;
+
+	pdata->target_reflectance_for_dmax_calc[0] = VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_0_DEFAULT;
+	pdata->target_reflectance_for_dmax_calc[1] = VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_1_DEFAULT;
+	pdata->target_reflectance_for_dmax_calc[2] = VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_2_DEFAULT;
+	pdata->target_reflectance_for_dmax_calc[3] = VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_3_DEFAULT;
+	pdata->target_reflectance_for_dmax_calc[4] = VL53LX_TUNINGPARM_DMAX_CFG_REFLECTANCE_ARRAY_4_DEFAULT;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_init_tuning_parm_storage_struct(VL53LX_tuning_parm_storage_t *pdata)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	pdata->tp_tuning_parm_version              = VL53LX_TUNINGPARM_VERSION_DEFAULT;
+	pdata->tp_tuning_parm_key_table_version    = VL53LX_TUNINGPARM_KEY_TABLE_VERSION_DEFAULT;
+	pdata->tp_tuning_parm_lld_version          = VL53LX_TUNINGPARM_LLD_VERSION_DEFAULT;
+	pdata->tp_init_phase_rtn_lite_long         = VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_LONG_RANGE_DEFAULT;
+	pdata->tp_init_phase_rtn_lite_med          = VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_MED_RANGE_DEFAULT;
+	pdata->tp_init_phase_rtn_lite_short        = VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_LITE_SHORT_RANGE_DEFAULT;
+	pdata->tp_init_phase_ref_lite_long         = VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_LONG_RANGE_DEFAULT;
+	pdata->tp_init_phase_ref_lite_med          = VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_MED_RANGE_DEFAULT;
+	pdata->tp_init_phase_ref_lite_short        = VL53LX_TUNINGPARM_INITIAL_PHASE_REF_LITE_SHORT_RANGE_DEFAULT;
+	pdata->tp_init_phase_rtn_hist_long         = VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_LONG_RANGE_DEFAULT;
+	pdata->tp_init_phase_rtn_hist_med          = VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_MED_RANGE_DEFAULT;
+	pdata->tp_init_phase_rtn_hist_short        = VL53LX_TUNINGPARM_INITIAL_PHASE_RTN_HISTO_SHORT_RANGE_DEFAULT;
+	pdata->tp_init_phase_ref_hist_long         = VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_LONG_RANGE_DEFAULT;
+	pdata->tp_init_phase_ref_hist_med          = VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_MED_RANGE_DEFAULT;
+	pdata->tp_init_phase_ref_hist_short        = VL53LX_TUNINGPARM_INITIAL_PHASE_REF_HISTO_SHORT_RANGE_DEFAULT;
+	pdata->tp_consistency_lite_phase_tolerance = VL53LX_TUNINGPARM_CONSISTENCY_LITE_PHASE_TOLERANCE_DEFAULT;
+	pdata->tp_phasecal_target                  = VL53LX_TUNINGPARM_PHASECAL_TARGET_DEFAULT;
+	pdata->tp_cal_repeat_rate                  = VL53LX_TUNINGPARM_LITE_CAL_REPEAT_RATE_DEFAULT;
+	pdata->tp_lite_min_clip                    = VL53LX_TUNINGPARM_LITE_MIN_CLIP_MM_DEFAULT;
+	pdata->tp_lite_long_sigma_thresh_mm        = VL53LX_TUNINGPARM_LITE_LONG_SIGMA_THRESH_MM_DEFAULT;
+	pdata->tp_lite_med_sigma_thresh_mm         = VL53LX_TUNINGPARM_LITE_MED_SIGMA_THRESH_MM_DEFAULT;
+	pdata->tp_lite_short_sigma_thresh_mm       = VL53LX_TUNINGPARM_LITE_SHORT_SIGMA_THRESH_MM_DEFAULT;
+	pdata->tp_lite_long_min_count_rate_rtn_mcps  = VL53LX_TUNINGPARM_LITE_LONG_MIN_COUNT_RATE_RTN_MCPS_DEFAULT;
+	pdata->tp_lite_med_min_count_rate_rtn_mcps   = VL53LX_TUNINGPARM_LITE_MED_MIN_COUNT_RATE_RTN_MCPS_DEFAULT;
+	pdata->tp_lite_short_min_count_rate_rtn_mcps = VL53LX_TUNINGPARM_LITE_SHORT_MIN_COUNT_RATE_RTN_MCPS_DEFAULT;
+	pdata->tp_lite_sigma_est_pulse_width_ns      = VL53LX_TUNINGPARM_LITE_SIGMA_EST_PULSE_WIDTH_DEFAULT;
+	pdata->tp_lite_sigma_est_amb_width_ns        = VL53LX_TUNINGPARM_LITE_SIGMA_EST_AMB_WIDTH_NS_DEFAULT;
+	pdata->tp_lite_sigma_ref_mm                  = VL53LX_TUNINGPARM_LITE_SIGMA_REF_MM_DEFAULT;
+	pdata->tp_lite_seed_cfg                      = VL53LX_TUNINGPARM_LITE_SEED_CONFIG_DEFAULT;
+	pdata->tp_timed_seed_cfg                     = VL53LX_TUNINGPARM_TIMED_SEED_CONFIG_DEFAULT;
+	pdata->tp_lite_quantifier                    = VL53LX_TUNINGPARM_LITE_QUANTIFIER_DEFAULT;
+	pdata->tp_lite_first_order_select            = VL53LX_TUNINGPARM_LITE_FIRST_ORDER_SELECT_DEFAULT;
+	pdata->tp_uwr_enable = VL53LX_TUNINGPARM_UWR_ENABLE_DEFAULT;
+	pdata->tp_uwr_med_z_1_min = VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MIN_DEFAULT;
+	pdata->tp_uwr_med_z_1_max = VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_1_MAX_DEFAULT;
+	pdata->tp_uwr_med_z_2_min = VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MIN_DEFAULT;
+	pdata->tp_uwr_med_z_2_max = VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_2_MAX_DEFAULT;
+	pdata->tp_uwr_med_z_3_min = VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MIN_DEFAULT;
+	pdata->tp_uwr_med_z_3_max = VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_3_MAX_DEFAULT;
+	pdata->tp_uwr_med_z_4_min = VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MIN_DEFAULT;
+	pdata->tp_uwr_med_z_4_max = VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_4_MAX_DEFAULT;
+	pdata->tp_uwr_med_z_5_min = VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MIN_DEFAULT;
+	pdata->tp_uwr_med_z_5_max = VL53LX_TUNINGPARM_UWR_MEDIUM_ZONE_5_MAX_DEFAULT;
+	pdata->tp_uwr_med_corr_z_1_rangea = VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEA_DEFAULT;
+	pdata->tp_uwr_med_corr_z_1_rangeb = VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_1_RANGEB_DEFAULT;
+	pdata->tp_uwr_med_corr_z_2_rangea = VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEA_DEFAULT;
+	pdata->tp_uwr_med_corr_z_2_rangeb = VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_2_RANGEB_DEFAULT;
+	pdata->tp_uwr_med_corr_z_3_rangea = VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEA_DEFAULT;
+	pdata->tp_uwr_med_corr_z_3_rangeb = VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_3_RANGEB_DEFAULT;
+	pdata->tp_uwr_med_corr_z_4_rangea = VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEA_DEFAULT;
+	pdata->tp_uwr_med_corr_z_4_rangeb = VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_4_RANGEB_DEFAULT;
+	pdata->tp_uwr_med_corr_z_5_rangea = VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEA_DEFAULT;
+	pdata->tp_uwr_med_corr_z_5_rangeb = VL53LX_TUNINGPARM_UWR_MEDIUM_CORRECTION_ZONE_5_RANGEB_DEFAULT;
+	pdata->tp_uwr_lng_z_1_min = VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MIN_DEFAULT;
+	pdata->tp_uwr_lng_z_1_max = VL53LX_TUNINGPARM_UWR_LONG_ZONE_1_MAX_DEFAULT;
+	pdata->tp_uwr_lng_z_2_min = VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MIN_DEFAULT;
+	pdata->tp_uwr_lng_z_2_max = VL53LX_TUNINGPARM_UWR_LONG_ZONE_2_MAX_DEFAULT;
+	pdata->tp_uwr_lng_z_3_min = VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MIN_DEFAULT;
+	pdata->tp_uwr_lng_z_3_max = VL53LX_TUNINGPARM_UWR_LONG_ZONE_3_MAX_DEFAULT;
+	pdata->tp_uwr_lng_z_4_min = VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MIN_DEFAULT;
+	pdata->tp_uwr_lng_z_4_max = VL53LX_TUNINGPARM_UWR_LONG_ZONE_4_MAX_DEFAULT;
+	pdata->tp_uwr_lng_z_5_min = VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MIN_DEFAULT;
+	pdata->tp_uwr_lng_z_5_max = VL53LX_TUNINGPARM_UWR_LONG_ZONE_5_MAX_DEFAULT;
+	pdata->tp_uwr_lng_corr_z_1_rangea = VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEA_DEFAULT;
+	pdata->tp_uwr_lng_corr_z_1_rangeb = VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_1_RANGEB_DEFAULT;
+	pdata->tp_uwr_lng_corr_z_2_rangea = VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEA_DEFAULT;
+	pdata->tp_uwr_lng_corr_z_2_rangeb = VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_2_RANGEB_DEFAULT;
+	pdata->tp_uwr_lng_corr_z_3_rangea = VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEA_DEFAULT;
+	pdata->tp_uwr_lng_corr_z_3_rangeb = VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_3_RANGEB_DEFAULT;
+	pdata->tp_uwr_lng_corr_z_4_rangea = VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEA_DEFAULT;
+	pdata->tp_uwr_lng_corr_z_4_rangeb = VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_4_RANGEB_DEFAULT;
+	pdata->tp_uwr_lng_corr_z_5_rangea = VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEA_DEFAULT;
+	pdata->tp_uwr_lng_corr_z_5_rangeb = VL53LX_TUNINGPARM_UWR_LONG_CORRECTION_ZONE_5_RANGEB_DEFAULT;
+
+	pdata->tp_dss_target_lite_mcps               = VL53LX_TUNINGPARM_LITE_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT;
+	pdata->tp_dss_target_histo_mcps              = VL53LX_TUNINGPARM_RANGING_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT;
+	pdata->tp_dss_target_histo_mz_mcps           = VL53LX_TUNINGPARM_MZ_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT;
+	pdata->tp_dss_target_timed_mcps              = VL53LX_TUNINGPARM_TIMED_DSS_CONFIG_TARGET_TOTAL_RATE_MCPS_DEFAULT;
+	pdata->tp_phasecal_timeout_lite_us           = VL53LX_TUNINGPARM_LITE_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_phasecal_timeout_hist_long_us      = VL53LX_TUNINGPARM_RANGING_LONG_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_phasecal_timeout_hist_med_us       = VL53LX_TUNINGPARM_RANGING_MED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_phasecal_timeout_hist_short_us     = VL53LX_TUNINGPARM_RANGING_SHORT_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_phasecal_timeout_mz_long_us        = VL53LX_TUNINGPARM_MZ_LONG_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_phasecal_timeout_mz_med_us         = VL53LX_TUNINGPARM_MZ_MED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_phasecal_timeout_mz_short_us       = VL53LX_TUNINGPARM_MZ_SHORT_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_phasecal_timeout_timed_us          = VL53LX_TUNINGPARM_TIMED_PHASECAL_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_mm_timeout_lite_us                 = VL53LX_TUNINGPARM_LITE_MM_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_mm_timeout_histo_us                = VL53LX_TUNINGPARM_RANGING_MM_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_mm_timeout_mz_us                   = VL53LX_TUNINGPARM_MZ_MM_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_mm_timeout_timed_us                = VL53LX_TUNINGPARM_TIMED_MM_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_range_timeout_lite_us              = VL53LX_TUNINGPARM_LITE_RANGE_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_range_timeout_histo_us             = VL53LX_TUNINGPARM_RANGING_RANGE_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_range_timeout_mz_us                = VL53LX_TUNINGPARM_MZ_RANGE_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_range_timeout_timed_us             = VL53LX_TUNINGPARM_TIMED_RANGE_CONFIG_TIMEOUT_US_DEFAULT;
+
+	pdata->tp_mm_timeout_lpa_us = VL53LX_TUNINGPARM_LOWPOWERAUTO_MM_CONFIG_TIMEOUT_US_DEFAULT;
+	pdata->tp_range_timeout_lpa_us = VL53LX_TUNINGPARM_LOWPOWERAUTO_RANGE_CONFIG_TIMEOUT_US_DEFAULT;
+
+	pdata->tp_dss_target_very_short_mcps = VL53LX_TUNINGPARM_VERY_SHORT_DSS_RATE_MCPS_DEFAULT;
+
+	pdata->tp_phasecal_patch_power = VL53LX_TUNINGPARM_PHASECAL_PATCH_POWER_DEFAULT;
+
+	pdata->tp_hist_merge = VL53LX_TUNINGPARM_HIST_MERGE_DEFAULT;
+
+	pdata->tp_reset_merge_threshold = VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD_DEFAULT;
+
+	pdata->tp_hist_merge_max_size = VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE_DEFAULT;
+
+	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 = VL53LX_ERROR_NONE;
+
+	status = VL53LX_preset_mode_histogram_ranging(phistpostprocess, pstatic, phistogram, pgeneral, ptiming, pdynamic, psystem, ptuning_parms, pzone_cfg);
+	if (status == 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, ptiming, pdynamic);
+
+		ptiming->range_config__vcsel_period_a = 0x03;
+		ptiming->range_config__vcsel_period_b = 0x05;
+
+		ptiming->mm_config__timeout_macrop_a_hi = 0x00;
+		ptiming->mm_config__timeout_macrop_a_lo = 0x52;
+		ptiming->mm_config__timeout_macrop_b_hi = 0x00;
+		ptiming->mm_config__timeout_macrop_b_lo = 0x37;
+
+		ptiming->range_config__timeout_macrop_a_hi = 0x00;
+		ptiming->range_config__timeout_macrop_a_lo = 0x66;
+		ptiming->range_config__timeout_macrop_b_hi = 0x00;
+		ptiming->range_config__timeout_macrop_b_lo = 0x44;
+
+		pgeneral->cal_config__vcsel_start = 0x03;
+
+		pgeneral->phasecal_config__timeout_macrop = 0xF5;
+
+		pdynamic->sd_config__woi_sd0 = 0x03;
+		pdynamic->sd_config__woi_sd1 = 0x05;
+		pdynamic->sd_config__initial_phase_sd0            = ptuning_parms->tp_init_phase_rtn_hist_short;
+		pdynamic->sd_config__initial_phase_sd1            = ptuning_parms->tp_init_phase_ref_hist_short;
+
+		phistpostprocess->valid_phase_low = 0x08;
+		phistpostprocess->valid_phase_high = 0x28;
+
+		pdynamic->system__sequence_config = VL53LX_SEQUENCE_VHV_EN | VL53LX_SEQUENCE_PHASECAL_EN | VL53LX_SEQUENCE_DSS1_EN | VL53LX_SEQUENCE_DSS2_EN | VL53LX_SEQUENCE_MM1_EN  | VL53LX_SEQUENCE_RANGE_EN;
+
+		psystem->system__mode_start = VL53LX_DEVICESCHEDULERMODE_HISTOGRAM | VL53LX_DEVICEREADOUTMODE_DUAL_SD | VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
+	}
+	return status;
+}
+
+void VL53LX_init_histogram_bin_data_struct(int32_t bin_value, uint16_t VL53LX_p_021, VL53LX_histogram_bin_data_t *pdata)
+{
+	uint16_t          i = 0;
+
+	pdata->cfg_device_state          = VL53LX_DEVICESTATE_SW_STANDBY;
+	pdata->rd_device_state           = VL53LX_DEVICESTATE_SW_STANDBY;
+	pdata->zone_id                   = 0;
+	pdata->time_stamp                = 0;
+	pdata->VL53LX_p_019                 = 0;
+	pdata->VL53LX_p_020               = VL53LX_HISTOGRAM_BUFFER_SIZE;
+	pdata->VL53LX_p_021            = (uint8_t)VL53LX_p_021;
+	pdata->number_of_ambient_bins    = 0;
+	pdata->result__interrupt_status           = 0;
+	pdata->result__range_status               = 0;
+	pdata->result__report_status              = 0;
+	pdata->result__stream_count               = 0;
+	pdata->result__dss_actual_effective_spads = 0;
+	pdata->phasecal_result__reference_phase   = 0;
+	pdata->phasecal_result__vcsel_start       = 0;
+	pdata->cal_config__vcsel_start            = 0;
+	pdata->vcsel_width                        = 0;
+	pdata->VL53LX_p_005                       = 0;
+	pdata->VL53LX_p_015                = 0;
+	pdata->total_periods_elapsed              = 0;
+	pdata->min_bin_value                      = 0;
+	pdata->max_bin_value                      = 0;
+	pdata->zero_distance_phase                = 0;
+	pdata->number_of_ambient_samples          = 0;
+	pdata->ambient_events_sum                 = 0;
+	pdata->VL53LX_p_028             = 0;
+
+	for (i = 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++)
+		pdata->bin_seq[i] = (uint8_t)i;
+
+	for (i = 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++)
+		pdata->bin_rep[i] = 1;
+
+	for (i = 0; i < VL53LX_HISTOGRAM_BUFFER_SIZE; i++)
+		if (i < VL53LX_p_021)
+			pdata->bin_data[i] = bin_value;
+		else
+			pdata->bin_data[i] = 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 = 0;
+
+	pdata->zone_id                   = 0;
+	pdata->time_stamp                = 0;
+	pdata->VL53LX_p_019                 = 0;
+	pdata->VL53LX_p_020               = VL53LX_XTALK_HISTO_BINS;
+	pdata->VL53LX_p_021            = (uint8_t)VL53LX_p_021;
+	pdata->phasecal_result__reference_phase   = 0;
+	pdata->phasecal_result__vcsel_start       = 0;
+	pdata->cal_config__vcsel_start            = 0;
+	pdata->vcsel_width                        = 0;
+	pdata->VL53LX_p_015                = 0;
+	pdata->zero_distance_phase                = 0;
+
+	for (i = 0; i < VL53LX_XTALK_HISTO_BINS; i++) {
+		if (i < VL53LX_p_021)
+			pdata->bin_data[i] = bin_value;
+		else
+			pdata->bin_data[i] = 0;
+	}
+}
+
+VL53LX_Error VL53LX_xtalk_cal_data_init(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps = 0;
+	pdev->xtalk_cal.algo__crosstalk_compensation_x_plane_gradient_kcps = 0;
+	pdev->xtalk_cal.algo__crosstalk_compensation_y_plane_gradient_kcps = 0;
+	memset(&pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0], 0, sizeof(pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps));
+
+	return status;
+}
+
+VL53LX_Error VL53LX_dynamic_xtalk_correction_output_init(VL53LX_LLDriverResults_t *pres)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_smudge_corrector_data_t *pdata;
+
+	pdata = &(pres->range_results.smudge_corrector_data);
+
+	pdata->smudge_corr_valid = 0;
+	pdata->smudge_corr_clipped = 0;
+	pdata->single_xtalk_delta_flag = 0;
+	pdata->averaged_xtalk_delta_flag = 0;
+	pdata->sample_limit_exceeded_flag = 0;
+	pdata->gradient_zero_flag = 0;
+	pdata->new_xtalk_applied_flag = 0;
+	pdata->algo__crosstalk_compensation_plane_offset_kcps = 0;
+	pdata->algo__crosstalk_compensation_x_plane_gradient_kcps = 0;
+	pdata->algo__crosstalk_compensation_y_plane_gradient_kcps = 0;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_dynamic_xtalk_correction_data_init(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+
+	pdev->smudge_correct_config.smudge_corr_enabled       = 1;
+	pdev->smudge_correct_config.smudge_corr_apply_enabled = 1;
+	pdev->smudge_correct_config.smudge_corr_single_apply  = VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_COR_SINGLE_APPLY_DEFAULT;
+	pdev->smudge_correct_config.smudge_margin = VL53LX_TUNINGPARM_DYNXTALK_SMUDGE_MARGIN_DEFAULT;
+	pdev->smudge_correct_config.noise_margin = VL53LX_TUNINGPARM_DYNXTALK_NOISE_MARGIN_DEFAULT;
+	pdev->smudge_correct_config.user_xtalk_offset_limit = VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_DEFAULT;
+	pdev->smudge_correct_config.user_xtalk_offset_limit_hi = VL53LX_TUNINGPARM_DYNXTALK_XTALK_OFFSET_LIMIT_HI_DEFAULT;
+	pdev->smudge_correct_config.sample_limit = VL53LX_TUNINGPARM_DYNXTALK_SAMPLE_LIMIT_DEFAULT;
+	pdev->smudge_correct_config.single_xtalk_delta = VL53LX_TUNINGPARM_DYNXTALK_SINGLE_XTALK_DELTA_DEFAULT;
+	pdev->smudge_correct_config.averaged_xtalk_delta = VL53LX_TUNINGPARM_DYNXTALK_AVERAGED_XTALK_DELTA_DEFAULT;
+	pdev->smudge_correct_config.smudge_corr_clip_limit = VL53LX_TUNINGPARM_DYNXTALK_CLIP_LIMIT_DEFAULT;
+	pdev->smudge_correct_config.smudge_corr_ambient_threshold = VL53LX_TUNINGPARM_DYNXTALK_XTALK_AMB_THRESHOLD_DEFAULT;
+	pdev->smudge_correct_config.scaler_calc_method = 0;
+	pdev->smudge_correct_config.x_gradient_scaler = VL53LX_TUNINGPARM_DYNXTALK_XGRADIENT_SCALER_DEFAULT;
+	pdev->smudge_correct_config.y_gradient_scaler = VL53LX_TUNINGPARM_DYNXTALK_YGRADIENT_SCALER_DEFAULT;
+	pdev->smudge_correct_config.user_scaler_set = VL53LX_TUNINGPARM_DYNXTALK_USER_SCALER_SET_DEFAULT;
+	pdev->smudge_correct_config.nodetect_ambient_threshold = VL53LX_TUNINGPARM_DYNXTALK_NODETECT_AMB_THRESHOLD_KCPS_DEFAULT;
+	pdev->smudge_correct_config.nodetect_sample_limit = VL53LX_TUNINGPARM_DYNXTALK_NODETECT_SAMPLE_LIMIT_DEFAULT;
+	pdev->smudge_correct_config.nodetect_xtalk_offset = VL53LX_TUNINGPARM_DYNXTALK_NODETECT_XTALK_OFFSET_KCPS_DEFAULT;
+	pdev->smudge_correct_config.nodetect_min_range_mm = VL53LX_TUNINGPARM_DYNXTALK_NODETECT_MIN_RANGE_MM_DEFAULT;
+	pdev->smudge_correct_config.max_smudge_factor = VL53LX_TUNINGPARM_DYNXTALK_MAX_SMUDGE_FACTOR_DEFAULT;
+	pdev->smudge_corrector_internals.current_samples = 0;
+	pdev->smudge_corrector_internals.required_samples = 0;
+	pdev->smudge_corrector_internals.accumulator = 0;
+	pdev->smudge_corrector_internals.nodetect_counter = 0;
+
+	VL53LX_dynamic_xtalk_correction_output_init(pres);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_low_power_auto_data_init(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->low_power_auto_data.vhv_loop_bound = VL53LX_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND_DEFAULT;
+	pdev->low_power_auto_data.is_low_power_auto_mode = 0;
+	pdev->low_power_auto_data.low_power_auto_range_count = 0;
+	pdev->low_power_auto_data.saved_interrupt_config = 0;
+	pdev->low_power_auto_data.saved_vhv_init = 0;
+	pdev->low_power_auto_data.saved_vhv_timeout = 0;
+	pdev->low_power_auto_data.first_run_phasecal_result = 0;
+	pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0;
+	pdev->low_power_auto_data.dss__required_spads = 0;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_data_init(VL53LX_DEV Dev, uint8_t read_p2p_data)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+	VL53LX_zone_objects_t    *pobjects;
+	uint8_t  i = 0;
+
+	VL53LX_init_ll_driver_state(Dev, VL53LX_DEVICESTATE_UNKNOWN);
+
+	pres->range_results.max_results    = VL53LX_MAX_RANGE_RESULTS;
+	pres->range_results.active_results = 0;
+	pres->zone_results.max_zones       = VL53LX_MAX_USER_ZONES;
+	pres->zone_results.active_zones    = 0;
+
+	for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) {
+		pobjects = &(pres->zone_results.VL53LX_p_003[i]);
+		pobjects->xmonitor.VL53LX_p_016 = 0;
+		pobjects->xmonitor.VL53LX_p_017 = 0;
+		pobjects->xmonitor.VL53LX_p_011 = 0;
+		pobjects->xmonitor.range_status = VL53LX_DEVICEERROR_NOUPDATE;
+	}
+
+	pres->zone_hists.max_zones = VL53LX_MAX_USER_ZONES;
+	pres->zone_hists.active_zones = 0;
+
+	pres->zone_cal.max_zones = VL53LX_MAX_USER_ZONES;
+
+	pres->zone_cal.active_zones = 0;
+	for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) {
+		pres->zone_cal.VL53LX_p_003[i].no_of_samples   = 0;
+		pres->zone_cal.VL53LX_p_003[i].effective_spads = 0;
+		pres->zone_cal.VL53LX_p_003[i].peak_rate_mcps  = 0;
+		pres->zone_cal.VL53LX_p_003[i].median_range_mm = 0;
+		pres->zone_cal.VL53LX_p_003[i].range_mm_offset = 0;
+	}
+
+	pdev->wait_method   = VL53LX_WAIT_METHOD_BLOCKING;
+	pdev->preset_mode   = VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE;
+	pdev->zone_preset   = 0;
+	pdev->measurement_mode = VL53LX_DEVICEMEASUREMENTMODE_STOP;
+
+	pdev->offset_calibration_mode = VL53LX_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD;
+	pdev->offset_correction_mode  = VL53LX_OFFSETCORRECTIONMODE__MM1_MM2_OFFSETS;
+	pdev->dmax_mode  = VL53LX_DEVICEDMAXMODE__FMT_CAL_DATA;
+
+	pdev->phasecal_config_timeout_us  =  1000;
+	pdev->mm_config_timeout_us        =  2000;
+	pdev->range_config_timeout_us     = 13000;
+	pdev->inter_measurement_period_ms =   100;
+	pdev->dss_config__target_total_rate_mcps = 0x0A00;
+	pdev->debug_mode                  =  0x00;
+
+	pdev->offset_results.max_results    = VL53LX_MAX_OFFSET_RANGE_RESULTS;
+	pdev->offset_results.active_results = 0;
+
+	pdev->gain_cal.standard_ranging_gain_factor = VL53LX_TUNINGPARM_LITE_RANGING_GAIN_FACTOR_DEFAULT;
+	pdev->gain_cal.histogram_ranging_gain_factor = VL53LX_TUNINGPARM_HIST_GAIN_FACTOR_DEFAULT;
+
+	VL53LX_init_version(Dev);
+
+	memset(pdev->multi_bins_rec, 0, sizeof(pdev->multi_bins_rec));
+	pdev->bin_rec_pos = 0;
+	pdev->pos_before_next_recom = 0;
+
+	if (read_p2p_data > 0 && status == VL53LX_ERROR_NONE)
+		status = VL53LX_read_p2p_data(Dev);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_refspadchar_config_struct(&(pdev->refspadchar));
+
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_ssc_config_struct(&(pdev->ssc_cfg));
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_xtalk_config_struct(&(pdev->customer), &(pdev->xtalk_cfg));
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_xtalk_extract_config_struct(&(pdev->xtalk_extract_cfg));
+
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_offset_cal_config_struct(&(pdev->offsetcal_cfg));
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_zone_cal_config_struct(&(pdev->zonecal_cfg));
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_hist_post_process_config_struct(pdev->xtalk_cfg.global_crosstalk_compensation_enable, &(pdev->histpostprocess));
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_hist_gen3_dmax_config_struct(&(pdev->dmax_cfg));
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_tuning_parm_storage_struct(&(pdev->tuning_parms));
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_set_preset_mode(Dev, pdev->preset_mode, pdev->dss_config__target_total_rate_mcps, pdev->phasecal_config_timeout_us, pdev->mm_config_timeout_us, pdev->range_config_timeout_us, pdev->inter_measurement_period_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->xtalk_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 dmax_mode)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->dmax_mode = dmax_mode;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_DataInit(VL53LX_DEV Dev)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev;
+	uint8_t  measurement_mode;
+
+#ifdef USE_I2C_2V8
+	Status = VL53LX_RdByte(Dev, VL53LX_PAD_I2C_HV__EXTSUP_CONFIG, &i);
+	if (Status == VL53LX_ERROR_NONE) {
+		i = (i & 0xfe) | 0x01;
+		Status = VL53LX_WrByte(Dev, VL53LX_PAD_I2C_HV__EXTSUP_CONFIG, i);
+	}
+#endif
+
+	if (Status == VL53LX_ERROR_NONE)
+		Status = VL53LX_data_init(Dev, 1);
+
+	if (Status == VL53LX_ERROR_NONE)
+		Status = SetPresetModeL3CX(Dev, VL53LX_DISTANCEMODE_MEDIUM, 1000);
+
+	if (Status == VL53LX_ERROR_NONE)
+		Status = VL53LX_SetMeasurementTimingBudgetMicroSeconds(Dev, 33333);
+
+	if (Status == VL53LX_ERROR_NONE) {
+		pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+		memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
+	}
+
+	if (Status == VL53LX_ERROR_NONE) {
+		Status = VL53LX_set_dmax_mode(Dev, VL53LX_DEVICEDMAXMODE__CUST_CAL_DATA);
+	}
+
+	if (Status == VL53LX_ERROR_NONE)
+		Status = VL53LX_SmudgeCorrectionEnable(Dev, VL53LX_SMUDGE_CORRECTION_NONE);
+
+	measurement_mode  = 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 = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = 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 = 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 = (2 * zone_cfg.user_zones[0].x_centre - zone_cfg.user_zones[0].width) >> 1;
+	TopLeftY = (2 * zone_cfg.user_zones[0].y_centre + zone_cfg.user_zones[0].height) >> 1;
+	BotRightX = (2 * zone_cfg.user_zones[0].x_centre + zone_cfg.user_zones[0].width) >> 1;
+	BotRightY = (2 * zone_cfg.user_zones[0].y_centre - zone_cfg.user_zones[0].height) >> 1;
+	pRoi->TopLeftX = TopLeftX;
+	pRoi->TopLeftY = TopLeftY;
+	pRoi->BotRightX = BotRightX;
+	pRoi->BotRightY = BotRightY;
+
+	return Status;
+}
+
+VL53LX_Error VL53LX_GetDeviceInfo(VL53LX_DEV Dev, VL53LX_DeviceInfo_t *pVL53LX_DeviceInfo)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	uint8_t revision_id;
+	VL53LX_LLDriverData_t   *pLLData;
+
+	pLLData =  VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pVL53LX_DeviceInfo->ProductType = pLLData->nvm_copy_data.identification__module_type;
+
+	revision_id = pLLData->nvm_copy_data.identification__revision_id;
+	pVL53LX_DeviceInfo->ProductRevisionMajor = 1;
+	pVL53LX_DeviceInfo->ProductRevisionMinor = (revision_id & 0xF0) >> 4;
+
+	return Status;
+}
+
+VL53LX_Error VL53LX_GetOpticalCenter(VL53LX_DEV Dev, FixPoint1616_t *pOpticalCenterX, FixPoint1616_t *pOpticalCenterY)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	VL53LX_calibration_data_t  CalibrationData;
+
+	*pOpticalCenterX = 0;
+	*pOpticalCenterY = 0;
+	Status = VL53LX_get_part_to_part_data(Dev, &CalibrationData);
+	if (Status == VL53LX_ERROR_NONE) {
+		*pOpticalCenterX = VL53LX_FIXPOINT44TOFIXPOINT1616(CalibrationData.optical_centre.x_centre);
+		*pOpticalCenterY = VL53LX_FIXPOINT44TOFIXPOINT1616(CalibrationData.optical_centre.y_centre);
+	}
+	return Status;
+}
+
+static int setup_tunings(struct stmvl53lx_data *data)
+{
+	int rc = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(tunings); i++) {
+		rc = VL53LX_SetTuningParameter(&data->stdev, tunings[i][0],
+			tunings[i][1]);
+		if (rc) {
+			rc = store_last_error(data, rc);
+			break;
+		}
+	}
+	return rc;
+}
+
+static int allocate_dev_id(void)
+{
+	int i;
+
+	mutex_lock(&dev_table_mutex);
+
+	for (i = 0; i < STMVL53LX_CFG_MAX_DEV; i++)
+		if (!stmvl53lx_dev_table[i])
+			break;
+	i = 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] = 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                      = 0;
+	int32_t    total_rate_pre = 0;
+	int32_t    total_rate_cur = 0;
+	int32_t    PrevBin, CurrBin;
+
+	total_rate_pre = 0;
+	total_rate_cur = 0;
+
+
+	for (bin = timing * 4; bin < HighIndex; bin++) {
+		total_rate_pre += pdev->multi_bins_rec[prev_pos][timing][bin];
+		total_rate_cur += pdata->bin_data[bin];
+	}
+
+	if ((total_rate_pre != 0) && (total_rate_cur != 0))
+		for (bin = timing * 4; bin < HighIndex; bin++) {
+			PrevBin = pdev->multi_bins_rec[prev_pos][timing][bin];
+			PrevBin = (PrevBin * 1000) / total_rate_pre;
+			CurrBin = pdata->bin_data[bin] * 1000 / total_rate_cur;
+			*pdiff_histo_stddev += (PrevBin - CurrBin) * (PrevBin - CurrBin);
+	}
+}
+
+static void vl53lx_histo_merge(VL53LX_DEV Dev, VL53LX_histogram_bin_data_t *pdata)
+{
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	uint16_t   bin                      = 0;
+	uint8_t    i                        = 0;
+	int32_t    TuningBinRecSize		    = 0;
+	uint8_t    recom_been_reset			= 0;
+	uint8_t    timing					= 0;
+	int32_t    rmt  = 0;
+	int32_t    diff_histo_stddev		= 0;
+	uint8_t    HighIndex, prev_pos;
+	uint8_t    BuffSize = VL53LX_HISTOGRAM_BUFFER_SIZE;
+	uint8_t    pos;
+
+	VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, &TuningBinRecSize);
+	VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_RESET_MERGE_THRESHOLD, &rmt);
+
+	if (pdev->pos_before_next_recom == 0) {
+		timing = 1 - pdata->result__stream_count % 2;
+
+		diff_histo_stddev = 0;
+		HighIndex = BuffSize - timing * 4;
+		if (pdev->bin_rec_pos > 0)
+			prev_pos = pdev->bin_rec_pos - 1;
+		else
+			prev_pos = (TuningBinRecSize - 1);
+
+		if (pdev->multi_bins_rec[prev_pos][timing][4] > 0)
+			vl53lx_diff_histo_stddev(pdev, pdata, timing, HighIndex, prev_pos, &diff_histo_stddev);
+
+		if (diff_histo_stddev >= rmt) {
+			memset(pdev->multi_bins_rec, 0, sizeof(pdev->multi_bins_rec));
+			pdev->bin_rec_pos = 0;
+			recom_been_reset = 1;
+			if (timing == 0)
+				pdev->pos_before_next_recom = VL53LX_FRAME_WAIT_EVENT;
+			else
+				pdev->pos_before_next_recom = VL53LX_FRAME_WAIT_EVENT + 1;
+		} else {
+			pos = pdev->bin_rec_pos;
+			for (i = 0; i < BuffSize; i++)
+				pdev->multi_bins_rec[pos][timing][i] = pdata->bin_data[i];
+		}
+		if (pdev->bin_rec_pos == (TuningBinRecSize - 1) && timing == 1)
+			pdev->bin_rec_pos = 0;
+		else if (timing == 1)
+			pdev->bin_rec_pos++;
+
+		if (!((recom_been_reset == 1) && (timing == 0)) &&
+			 (pdev->pos_before_next_recom == 0)) {
+
+			for (bin = 0; bin < BuffSize; bin++)
+				pdata->bin_data[bin] = 0;
+
+			for (bin = 0; bin < BuffSize; bin++)
+				for (i = 0; i < TuningBinRecSize; i++)
+					pdata->bin_data[bin] += (pdev->multi_bins_rec[i][timing][bin]);
+		}
+	} else {
+
+		pdev->pos_before_next_recom--;
+		if (pdev->pos_before_next_recom == 255)
+			pdev->pos_before_next_recom = 0;
+	}
+}
+
+void VL53LX_hist_get_bin_sequence_config(VL53LX_DEV Dev, VL53LX_histogram_bin_data_t *pdata)
+{
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	int32_t amb_thresh_low   = 0;
+	int32_t amb_thresh_high  = 0;
+	uint8_t i = 0;
+
+	amb_thresh_low  = 1024 * (int32_t)pdev->hist_cfg.histogram_config__amb_thresh_low;
+	amb_thresh_high = 1024 * (int32_t)pdev->hist_cfg.histogram_config__amb_thresh_high;
+
+	if ((pdev->ll_state.rd_stream_count & 0x01) == 0) {
+		pdata->bin_seq[5] = pdev->hist_cfg.histogram_config__mid_amb_even_bin_4_5 >> 4;
+		pdata->bin_seq[4] = pdev->hist_cfg.histogram_config__mid_amb_even_bin_4_5 & 0x0F;
+		pdata->bin_seq[3] = pdev->hist_cfg.histogram_config__mid_amb_even_bin_2_3 >> 4;
+		pdata->bin_seq[2] = pdev->hist_cfg.histogram_config__mid_amb_even_bin_2_3 & 0x0F;
+		pdata->bin_seq[1] = pdev->hist_cfg.histogram_config__mid_amb_even_bin_0_1 >> 4;
+		pdata->bin_seq[0] = pdev->hist_cfg.histogram_config__mid_amb_even_bin_0_1 & 0x0F;
+
+		if (pdata->ambient_events_sum > amb_thresh_high) {
+			pdata->bin_seq[5] = pdev->hist_cfg.histogram_config__high_amb_even_bin_4_5 >> 4;
+			pdata->bin_seq[4] = pdev->hist_cfg.histogram_config__high_amb_even_bin_4_5 & 0x0F;
+			pdata->bin_seq[3] = pdev->hist_cfg.histogram_config__high_amb_even_bin_2_3 >> 4;
+			pdata->bin_seq[2] = pdev->hist_cfg.histogram_config__high_amb_even_bin_2_3 & 0x0F;
+			pdata->bin_seq[1] = pdev->hist_cfg.histogram_config__high_amb_even_bin_0_1 >> 4;
+			pdata->bin_seq[0] = pdev->hist_cfg.histogram_config__high_amb_even_bin_0_1 & 0x0F;
+		}
+		if (pdata->ambient_events_sum < amb_thresh_low) {
+			pdata->bin_seq[5] = pdev->hist_cfg.histogram_config__low_amb_even_bin_4_5 >> 4;
+			pdata->bin_seq[4] = pdev->hist_cfg.histogram_config__low_amb_even_bin_4_5 & 0x0F;
+			pdata->bin_seq[3] = pdev->hist_cfg.histogram_config__low_amb_even_bin_2_3 >> 4;
+			pdata->bin_seq[2] = pdev->hist_cfg.histogram_config__low_amb_even_bin_2_3 & 0x0F;
+			pdata->bin_seq[1] = pdev->hist_cfg.histogram_config__low_amb_even_bin_0_1 >> 4;
+			pdata->bin_seq[0] = pdev->hist_cfg.histogram_config__low_amb_even_bin_0_1 & 0x0F;
+		}
+
+	} else {
+		pdata->bin_seq[5] = pdev->hist_cfg.histogram_config__mid_amb_odd_bin_5 & 0x0F;
+		pdata->bin_seq[4] = pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3_4 & 0x0F;
+		pdata->bin_seq[3] = pdev->hist_cfg.histogram_config__mid_amb_odd_bin_3_4 >> 4;
+		pdata->bin_seq[2] = pdev->hist_cfg.histogram_config__mid_amb_odd_bin_2 & 0x0F;
+		pdata->bin_seq[1] = pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0_1 >> 4;
+		pdata->bin_seq[0] = pdev->hist_cfg.histogram_config__mid_amb_odd_bin_0_1 & 0x0F;
+		if (pdata->ambient_events_sum > amb_thresh_high) {
+			pdata->bin_seq[5] = pdev->hist_cfg.histogram_config__high_amb_odd_bin_4_5 >> 4;
+			pdata->bin_seq[4] = pdev->hist_cfg.histogram_config__high_amb_odd_bin_4_5 & 0x0F;
+			pdata->bin_seq[3] = pdev->hist_cfg.histogram_config__high_amb_odd_bin_2_3 >> 4;
+			pdata->bin_seq[2] = pdev->hist_cfg.histogram_config__high_amb_odd_bin_2_3 & 0x0F;
+			pdata->bin_seq[1] = pdev->hist_cfg.histogram_config__high_amb_odd_bin_0_1 >> 4;
+			pdata->bin_seq[0] = pdev->hist_cfg.histogram_config__high_amb_odd_bin_0_1 & 0x0F;
+		}
+		if (pdata->ambient_events_sum < amb_thresh_low) {
+			pdata->bin_seq[5] = pdev->hist_cfg.histogram_config__low_amb_odd_bin_4_5 >> 4;
+			pdata->bin_seq[4] = pdev->hist_cfg.histogram_config__low_amb_odd_bin_4_5 & 0x0F;
+			pdata->bin_seq[3] = pdev->hist_cfg.histogram_config__low_amb_odd_bin_2_3 >> 4;
+			pdata->bin_seq[2] = pdev->hist_cfg.histogram_config__low_amb_odd_bin_2_3 & 0x0F;
+			pdata->bin_seq[1] = pdev->hist_cfg.histogram_config__low_amb_odd_bin_0_1 >> 4;
+			pdata->bin_seq[0] = pdev->hist_cfg.histogram_config__low_amb_odd_bin_0_1 & 0x0F;
+		}
+	}
+	for (i = 0; i < VL53LX_MAX_BIN_SEQUENCE_LENGTH; i++)
+		pdata->bin_rep[i] = 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 = 0;
+	uint32_t  duration_us  = 0;
+
+	duration_us = window_vclks * pll_period_us;
+	duration_us = duration_us >> 12;
+	tmp_long_int = (uint64_t)duration_us;
+	duration_us = elapsed_mclks * vcsel_parm_pclks;
+	duration_us = duration_us >> 4;
+	tmp_long_int = tmp_long_int * (uint64_t)duration_us;
+	tmp_long_int = tmp_long_int >> 12;
+	if (tmp_long_int > 0xFFFFFFFF)
+		tmp_long_int = 0xFFFFFFFF;
+
+	duration_us  = (uint32_t)tmp_long_int;
+	return duration_us;
+}
+
+void VL53LX_hist_calc_zero_distance_phase(VL53LX_histogram_bin_data_t *pdata)
+{
+	uint32_t  period        = 0;
+	uint32_t  VL53LX_p_014         = 0;
+
+	period = 2048 * (uint32_t)VL53LX_decode_vcsel_period(pdata->VL53LX_p_005);
+
+	VL53LX_p_014  = period;
+	VL53LX_p_014 += (uint32_t)pdata->phasecal_result__reference_phase;
+	VL53LX_p_014 += (2048 * (uint32_t)pdata->phasecal_result__vcsel_start);
+	VL53LX_p_014 -= (2048 * (uint32_t)pdata->cal_config__vcsel_start);
+
+	if (period != 0)
+		VL53LX_p_014  = VL53LX_p_014 % period;
+	else
+		VL53LX_p_014 = 0;
+
+	pdata->zero_distance_phase = (uint16_t)VL53LX_p_014;
+}
+
+void VL53LX_hist_estimate_ambient_from_ambient_bins(VL53LX_histogram_bin_data_t *pdata)
+{
+	uint8_t  bin            = 0;
+
+	if (pdata->number_of_ambient_bins > 0) {
+		pdata->number_of_ambient_samples = pdata->number_of_ambient_bins;
+		pdata->ambient_events_sum = 0;
+		for (bin = 0; bin < pdata->number_of_ambient_bins; bin++)
+			pdata->ambient_events_sum += pdata->bin_data[bin];
+
+		pdata->VL53LX_p_028 = pdata->ambient_events_sum;
+		pdata->VL53LX_p_028 += ((int32_t)pdata->number_of_ambient_bins / 2);
+		pdata->VL53LX_p_028 /= (int32_t)pdata->number_of_ambient_bins;
+	}
+}
+
+VL53LX_Error VL53LX_get_histogram_bin_data(VL53LX_DEV Dev, VL53LX_histogram_bin_data_t *pdata)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+	VL53LX_zone_private_dyn_cfg_t *pzone_dyn_cfg;
+	VL53LX_static_nvm_managed_t   *pstat_nvm = &(pdev->stat_nvm);
+	VL53LX_static_config_t        *pstat_cfg = &(pdev->stat_cfg);
+	VL53LX_general_config_t       *pgen_cfg  = &(pdev->gen_cfg);
+	VL53LX_timing_config_t        *ptim_cfg  = &(pdev->tim_cfg);
+	VL53LX_range_results_t        *presults  = &(pres->range_results);
+
+	uint8_t    buffer[VL53LX_MAX_I2C_XFER_SIZE];
+	uint8_t   *pbuffer = &buffer[0];
+	uint8_t    bin_23_0 = 0x00;
+	uint16_t   bin                      = 0;
+	uint16_t   i2c_buffer_offset_bytes  = 0;
+	uint16_t   encoded_timeout          = 0;
+
+	uint32_t   pll_period_us            = 0;
+	uint32_t   periods_elapsed_tmp      = 0;
+
+	uint8_t    i                        = 0;
+
+	int32_t    hist_merge				= 0;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_ReadMulti(Dev, VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX, pbuffer, VL53LX_HISTOGRAM_BIN_DATA_I2C_SIZE_BYTES);
+
+	pdata->result__interrupt_status               = *(pbuffer +   0);
+	pdata->result__range_status                   = *(pbuffer +   1);
+	pdata->result__report_status                  = *(pbuffer +   2);
+	pdata->result__stream_count                   = *(pbuffer +   3);
+	pdata->result__dss_actual_effective_spads = VL53LX_i2c_decode_uint16_t(2, pbuffer +   4);
+
+	i2c_buffer_offset_bytes = VL53LX_PHASECAL_RESULT__REFERENCE_PHASE - VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
+
+	pbuffer = &buffer[i2c_buffer_offset_bytes];
+
+	pdata->phasecal_result__reference_phase = VL53LX_i2c_decode_uint16_t(2, pbuffer);
+
+	i2c_buffer_offset_bytes = VL53LX_PHASECAL_RESULT__VCSEL_START - VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
+
+	pdata->phasecal_result__vcsel_start = buffer[i2c_buffer_offset_bytes];
+
+	pdev->dbg_results.phasecal_result__reference_phase = pdata->phasecal_result__reference_phase;
+	pdev->dbg_results.phasecal_result__vcsel_start = pdata->phasecal_result__vcsel_start;
+
+	i2c_buffer_offset_bytes = VL53LX_RESULT__HISTOGRAM_BIN_23_0_MSB - VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
+
+	bin_23_0 = buffer[i2c_buffer_offset_bytes] << 2;
+
+	i2c_buffer_offset_bytes = VL53LX_RESULT__HISTOGRAM_BIN_23_0_LSB - VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
+
+	bin_23_0 += buffer[i2c_buffer_offset_bytes];
+
+	i2c_buffer_offset_bytes = VL53LX_RESULT__HISTOGRAM_BIN_23_0 - VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
+
+	buffer[i2c_buffer_offset_bytes] = bin_23_0;
+
+	i2c_buffer_offset_bytes = VL53LX_RESULT__HISTOGRAM_BIN_0_2 - VL53LX_HISTOGRAM_BIN_DATA_I2C_INDEX;
+
+	pbuffer = &buffer[i2c_buffer_offset_bytes];
+	for (bin = 0; bin < VL53LX_HISTOGRAM_BUFFER_SIZE; bin++) {
+		pdata->bin_data[bin] = (int32_t)VL53LX_i2c_decode_uint32_t(3, pbuffer);
+		pbuffer += 3;
+	}
+
+	VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE, &hist_merge);
+	if (pdata->result__stream_count == 0) {
+
+		memset(pdev->multi_bins_rec, 0, sizeof(pdev->multi_bins_rec));
+		pdev->bin_rec_pos = 0;
+		pdev->pos_before_next_recom = 0;
+	}
+	if (hist_merge == 1)
+		vl53lx_histo_merge(Dev, pdata);
+
+	pdata->zone_id                 = pdev->ll_state.rd_zone_id;
+	pdata->VL53LX_p_019               = 0;
+	pdata->VL53LX_p_020             = VL53LX_HISTOGRAM_BUFFER_SIZE;
+	pdata->VL53LX_p_021          = VL53LX_HISTOGRAM_BUFFER_SIZE;
+
+	pdata->cal_config__vcsel_start = pgen_cfg->cal_config__vcsel_start;
+
+
+
+	pdata->vcsel_width = ((uint16_t)pgen_cfg->global_config__vcsel_width) << 4;
+	pdata->vcsel_width += (uint16_t)pstat_cfg->ana_config__vcsel_pulse_width_offset;
+
+	pdata->VL53LX_p_015 = pstat_nvm->osc_measured__fast_osc__frequency;
+
+	VL53LX_hist_get_bin_sequence_config(Dev, pdata);
+
+	if (pdev->ll_state.rd_timing_status == 0) {
+		encoded_timeout = (ptim_cfg->range_config__timeout_macrop_a_hi << 8) + ptim_cfg->range_config__timeout_macrop_a_lo;
+		pdata->VL53LX_p_005 =  ptim_cfg->range_config__vcsel_period_a;
+	} else {
+		encoded_timeout = (ptim_cfg->range_config__timeout_macrop_b_hi << 8) + ptim_cfg->range_config__timeout_macrop_b_lo;
+		pdata->VL53LX_p_005 = ptim_cfg->range_config__vcsel_period_b;
+	}
+
+	pdata->number_of_ambient_bins  = 0;
+	for (i = 0; i < 6; i++) {
+		if ((pdata->bin_seq[i] & 0x07) == 0x07)
+			pdata->number_of_ambient_bins = pdata->number_of_ambient_bins + 0x04;
+	}
+	pdata->total_periods_elapsed = VL53LX_decode_timeout(encoded_timeout);
+
+	pll_period_us = VL53LX_calc_pll_period_us(pdata->VL53LX_p_015);
+
+	periods_elapsed_tmp = pdata->total_periods_elapsed + 1;
+
+	pdata->peak_duration_us = VL53LX_duration_maths(pll_period_us, (uint32_t)pdata->vcsel_width, VL53LX_RANGING_WINDOW_VCSEL_PERIODS, periods_elapsed_tmp);
+
+	pdata->woi_duration_us     = 0;
+
+	VL53LX_hist_calc_zero_distance_phase(pdata);
+	VL53LX_hist_estimate_ambient_from_ambient_bins(pdata);
+
+	pdata->cfg_device_state = pdev->ll_state.cfg_device_state;
+	pdata->rd_device_state  = pdev->ll_state.rd_device_state;
+
+	pzone_dyn_cfg = &(pres->zone_dyn_cfgs.VL53LX_p_003[pdata->zone_id]);
+
+	pdata->roi_config__user_roi_centre_spad = pzone_dyn_cfg->roi_config__user_roi_centre_spad;
+	pdata->roi_config__user_roi_requested_global_xy_size = pzone_dyn_cfg->roi_config__user_roi_requested_global_xy_size;
+
+	presults->device_status = VL53LX_DEVICEERROR_NOUPDATE;
+
+	switch (pdata->result__range_status & VL53LX_RANGE_STATUS__RANGE_STATUS_MASK) {
+	case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE:
+	case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE:
+	case VL53LX_DEVICEERROR_NOVHVVALUEFOUND:
+	case VL53LX_DEVICEERROR_USERROICLIP:
+	case VL53LX_DEVICEERROR_MULTCLIPFAIL:
+		presults->device_status = (pdata->result__range_status & VL53LX_RANGE_STATUS__RANGE_STATUS_MASK);
+		status = 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 = VL53LX_ERROR_NONE;
+
+	int64_t  evts              = 0;
+	int64_t  tmpi              = 0;
+	int64_t  tmpo              = 0;
+
+	if (pidata->result__dss_actual_effective_spads == 0) {
+		status = VL53LX_ERROR_DIVISION_BY_ZERO;
+	} else {
+		if (pidata->number_of_ambient_bins >  0 &&
+			podata->number_of_ambient_bins == 0) {
+			tmpo    = 1 + (int64_t)podata->total_periods_elapsed;
+			tmpo   *= (int64_t)podata->result__dss_actual_effective_spads;
+			tmpi    = 1 + (int64_t)pidata->total_periods_elapsed;
+			tmpi   *= (int64_t)pidata->result__dss_actual_effective_spads;
+			evts  = tmpo * (int64_t)pidata->ambient_events_sum;
+			evts += (tmpi/2);
+			if (tmpi != 0)
+				evts = do_division_s(evts, tmpi);
+
+			podata->ambient_events_sum = (int32_t)evts;
+			podata->VL53LX_p_028 = podata->ambient_events_sum;
+			podata->VL53LX_p_028 += ((int32_t)pidata->number_of_ambient_bins / 2);
+			podata->VL53LX_p_028 /= (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 = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	uint8_t i, timing;
+	uint8_t sum = 0;
+
+	timing = (pdev->hist_data.bin_seq[0] == 7 ? 1 : 0);
+	for (i = 0; i < VL53LX_BIN_REC_SIZE; i++)
+		if (pdev->multi_bins_rec[i][timing][7] > 0)
+			sum++;
+	*histo_merge_nb = 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 = 0;
+	uint16_t max_mm_outer_effective_spads = 0;
+	uint16_t mm_inner_effective_spads     = 0;
+	uint16_t mm_outer_effective_spads     = 0;
+	uint32_t scaled_mm1_peak_rate_mcps    = 0;
+	uint32_t scaled_mm2_peak_rate_mcps    = 0;
+	int32_t tmp0 = 0;
+	int32_t tmp1 = 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 == 0) ||
+		(max_mm_outer_effective_spads == 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  = (uint32_t)pcal_data->result__mm_inner_peak_signal_count_rtn_mcps;
+	scaled_mm1_peak_rate_mcps *= (uint32_t)mm_inner_effective_spads;
+	scaled_mm1_peak_rate_mcps /= (uint32_t)max_mm_inner_effective_spads;
+
+	scaled_mm2_peak_rate_mcps  = (uint32_t)pcal_data->result__mm_outer_peak_signal_count_rtn_mcps;
+	scaled_mm2_peak_rate_mcps *= (uint32_t)mm_outer_effective_spads;
+	scaled_mm2_peak_rate_mcps /= (uint32_t)max_mm_outer_effective_spads;
+
+	tmp0  = ((int32_t)mm1_offset_mm * (int32_t)scaled_mm1_peak_rate_mcps);
+	tmp0 += ((int32_t)mm2_offset_mm * (int32_t)scaled_mm2_peak_rate_mcps);
+
+	tmp1 =  (int32_t)scaled_mm1_peak_rate_mcps + (int32_t)scaled_mm2_peak_rate_mcps;
+
+	if (tmp1 != 0)
+		tmp0 = (tmp0 * 4) / tmp1;
+FAIL:
+	*prange_offset_mm = (int16_t)tmp0;
+
+}
+
+static VL53LX_Error select_offset_per_vcsel(VL53LX_LLDriverData_t *pdev, int16_t *poffset)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	int16_t tA, tB;
+	uint8_t isc;
+
+	switch (pdev->preset_mode) {
+	case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE:
+		tA = pdev->per_vcsel_cal_data.short_a_offset_mm;
+		tB = pdev->per_vcsel_cal_data.short_b_offset_mm;
+		break;
+	case VL53LX_DEVICEPRESETMODE_HISTOGRAM_MEDIUM_RANGE:
+		tA = pdev->per_vcsel_cal_data.medium_a_offset_mm;
+		tB = pdev->per_vcsel_cal_data.medium_b_offset_mm;
+		break;
+	case VL53LX_DEVICEPRESETMODE_HISTOGRAM_LONG_RANGE:
+		tA = pdev->per_vcsel_cal_data.long_a_offset_mm;
+		tB = pdev->per_vcsel_cal_data.long_b_offset_mm;
+		break;
+	default:
+		tA = pdev->per_vcsel_cal_data.long_a_offset_mm;
+		tB = pdev->per_vcsel_cal_data.long_b_offset_mm;
+		status = VL53LX_ERROR_INVALID_PARAMS;
+		*poffset = 0;
+		break;
+	}
+
+	isc = pdev->ll_state.cfg_internal_stream_count;
+	if (status == VL53LX_ERROR_NONE)
+		*poffset = (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, uint16_t *pmax_effective_spads)
+{
+	int16_t   x         = 0;
+	int16_t   y         = 0;
+	int16_t   zone_x_ll = 0;
+	int16_t   zone_y_ll = 0;
+	int16_t   zone_x_ur = 0;
+	int16_t   zone_y_ur = 0;
+	uint8_t   spad_number = 0;
+	uint8_t   byte_index  = 0;
+	uint8_t   bit_index   = 0;
+	uint8_t   bit_mask    = 0;
+	uint8_t   is_aperture = 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 = 0;
+	for (y = zone_y_ll; y <= zone_y_ur; y++) {
+		for (x = zone_x_ll; x <= 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_index, &bit_mask);
+			if ((pgood_spads[byte_index] & bit_mask) > 0) {
+				is_aperture = VL53LX_is_aperture_location((uint8_t)y, (uint8_t)x);
+				if (is_aperture > 0)
+					*pmax_effective_spads += aperture_attenuation;
+				else
+					*pmax_effective_spads += 0x0100;
+			}
+		}
+	}
+}
+
+VL53LX_Error VL53LX_get_dmax_calibration_data(VL53LX_DEV Dev, VL53LX_DeviceDmaxMode dmax_mode, VL53LX_dmax_calibration_data_t *pdmax_cal)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = 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 = VL53LX_ERROR_INVALID_PARAMS;
+		break;
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_f_031(VL53LX_histogram_bin_data_t *pidata, VL53LX_histogram_bin_data_t *podata)
+{
+	VL53LX_Error status = 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        = 0;
+	uint8_t  bin_seq_length = 0;
+	int32_t  repeat_count   = 0;
+	uint8_t  VL53LX_p_032       = 0;
+	uint8_t  lc       = 0;
+	uint8_t  i       = 0;
+
+	memcpy(podata, pidata, sizeof(VL53LX_histogram_bin_data_t));
+
+	podata->VL53LX_p_021 = 0;
+
+	for (lc = 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++)
+		podata->bin_seq[lc] = VL53LX_MAX_BIN_SEQUENCE_CODE+1;
+
+	for (lc = 0 ; lc < podata->VL53LX_p_020 ; lc++)
+		podata->bin_data[lc] = 0;
+
+	for (lc = 0 ; lc <= VL53LX_MAX_BIN_SEQUENCE_CODE ; lc++) {
+		bin_initial_index[lc] = 0x00;
+		bin_repeat_count[lc]  = 0x00;
+	}
+
+	bin_seq_length = 0x00;
+
+	for (lc = 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) {
+		bin_cfg = pidata->bin_seq[lc];
+
+		if (bin_repeat_count[bin_cfg] == 0) {
+			bin_initial_index[bin_cfg]      = bin_seq_length * 4;
+			podata->bin_seq[bin_seq_length] = bin_cfg;
+			bin_seq_length++;
+		}
+		bin_repeat_count[bin_cfg]++;
+
+		VL53LX_p_032 = bin_initial_index[bin_cfg];
+
+		for (i = 0 ; i < 4 ; i++)
+			podata->bin_data[VL53LX_p_032+i] +=
+				pidata->bin_data[lc*4+i];
+
+	}
+	for (lc = 0 ; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH ; lc++) {
+		bin_cfg = podata->bin_seq[lc];
+
+		if (bin_cfg <= VL53LX_MAX_BIN_SEQUENCE_CODE)
+			podata->bin_rep[lc] =
+				bin_repeat_count[bin_cfg];
+		else
+			podata->bin_rep[lc] = 0;
+	}
+	podata->VL53LX_p_021 = bin_seq_length * 4;
+
+	for (lc = 0 ; lc <= VL53LX_MAX_BIN_SEQUENCE_CODE ; lc++) {
+		repeat_count = (int32_t)bin_repeat_count[lc];
+		if (repeat_count > 0) {
+			VL53LX_p_032 = bin_initial_index[lc];
+			for (i = 0 ; i < 4 ; i++) {
+				podata->bin_data[VL53LX_p_032+i] += (repeat_count/2);
+				podata->bin_data[VL53LX_p_032+i] /= repeat_count;
+			}
+		}
+	}
+	podata->number_of_ambient_bins = 0;
+	if ((bin_repeat_count[7] > 0) || (bin_repeat_count[15] > 0))
+		podata->number_of_ambient_bins = 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_effective_spads, uint8_t roi_centre_spad, uint8_t roi_xy_size, uint32_t *xtalk_rate_kcps)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	uint8_t row = 0;
+	uint8_t col = 0;
+	int16_t  bound_l_x = 0;
+	int16_t  bound_r_x = 0;
+	int16_t  bound_u_y = 0;
+	int16_t  bound_d_y = 0;
+	int64_t xtalk_rate_ll = 0;
+	int64_t xtalk_rate_ur = 0;
+	int64_t xtalk_avg = 0;
+
+	if (status == VL53LX_ERROR_NONE) {
+		VL53LX_decode_row_col(roi_centre_spad, &row, &col);
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+		if ((((int16_t)roi_xy_size / 16) & 0x01) == 1)
+			bound_l_x = (int16_t) col - (((int16_t)roi_xy_size / 32) + 1);
+		else
+			bound_l_x = (int16_t) col - ((int16_t)roi_xy_size / 32);
+
+		bound_r_x = (int16_t) col + ((int16_t)roi_xy_size / 32);
+
+		if ((((int16_t)roi_xy_size) & 0x01) == 1)
+			bound_d_y = (int16_t) row - ((((int16_t)roi_xy_size & 0x0f) / 2) + 1);
+		else
+			bound_d_y = (int16_t) row - (((int16_t)roi_xy_size & 0x0f) / 2);
+
+		bound_u_y = (int16_t) row + (((int16_t)roi_xy_size & 0xf) / 2);
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+		bound_l_x =  (2 * bound_l_x) - 15 + (2 * (int16_t)centre_offset_x);
+		bound_r_x =  (2 * bound_r_x) - 15 + (2 * (int16_t)centre_offset_x);
+		bound_u_y =  (2 * bound_u_y) - 15 + (2 * (int16_t)centre_offset_y);
+		bound_d_y =  (2 * bound_d_y) - 15 + (2 * (int16_t)centre_offset_y);
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+		xtalk_rate_ll  = ((int64_t)bound_l_x * ((int64_t)xgradient)) + ((int64_t)bound_d_y * ((int64_t)ygradient));
+		xtalk_rate_ll  = do_division_s((xtalk_rate_ll + 1), 2);
+		xtalk_rate_ll += ((int64_t)mean_offset * 4);
+
+		xtalk_rate_ur  = ((int64_t)bound_r_x * ((int64_t)xgradient)) + ((int64_t)bound_u_y * ((int64_t)ygradient));
+		xtalk_rate_ur  = do_division_s((xtalk_rate_ur + 1), 2);
+		xtalk_rate_ur += ((int64_t)mean_offset * 4);
+	}
+
+	if (status == VL53LX_ERROR_NONE)
+		xtalk_avg = do_division_s(((xtalk_rate_ll + xtalk_rate_ur) + 1), 2);
+
+	if (status == VL53LX_ERROR_NONE)
+		if (xtalk_avg < 0)
+			xtalk_avg = 0;
+
+	*xtalk_rate_kcps = (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_histogram_bin_data_t *pxtalkcount_data)
+{
+	VL53LX_Error status              = VL53LX_ERROR_NONE;
+
+	uint64_t xtalk_events_per_spad = 0;
+	uint64_t xtalk_total_events = 0;
+	uint64_t xtalk_temp_bin = 0;
+	uint8_t  i = 0;
+
+	xtalk_events_per_spad = do_division_u((((uint64_t)xtalk_rate_kcps * (uint64_t)phist_data->peak_duration_us) + 500), 1000);
+
+	xtalk_total_events = xtalk_events_per_spad * (uint64_t)phist_data->result__dss_actual_effective_spads;
+	xtalk_total_events = do_division_u((xtalk_total_events), 256);
+	xtalk_total_events = do_division_u((xtalk_total_events + 1024), 2048);
+
+	if (xtalk_total_events > 0xFFFFFFFF)
+		xtalk_total_events = 0xFFFFFFFF;
+
+	for (i = 0; i < pxtalk_data->VL53LX_p_021; i++) {
+		xtalk_temp_bin = (uint64_t)pxtalk_data->bin_data[i] * (uint64_t)xtalk_total_events;
+		xtalk_temp_bin = do_division_u((xtalk_temp_bin + 512), 1024);
+		pxtalkcount_data->bin_data[i] = (uint32_t)xtalk_temp_bin;
+	}
+	return status;
+}
+
+void VL53LX_copy_xtalk_bin_data_to_histogram_data_struct(VL53LX_xtalk_histogram_shape_t *pxtalk, VL53LX_histogram_bin_data_t *phist)
+{
+	phist->cal_config__vcsel_start = pxtalk->cal_config__vcsel_start;
+	phist->VL53LX_p_015 = pxtalk->VL53LX_p_015;
+	phist->VL53LX_p_019 = pxtalk->VL53LX_p_019;
+
+	phist->phasecal_result__reference_phase = pxtalk->phasecal_result__reference_phase;
+	phist->phasecal_result__vcsel_start = pxtalk->phasecal_result__vcsel_start;
+
+	phist->vcsel_width = pxtalk->vcsel_width;
+	phist->zero_distance_phase = pxtalk->zero_distance_phase;
+
+	phist->zone_id      = pxtalk->zone_id;
+	phist->VL53LX_p_020  = pxtalk->VL53LX_p_020;
+	phist->time_stamp   = pxtalk->time_stamp;
+}
+
+void VL53LX_f_003(VL53LX_hist_gen3_algo_private_data_t *palgo)
+{
+	uint8_t lb = 0;
+	palgo->VL53LX_p_020 = VL53LX_HISTOGRAM_BUFFER_SIZE;
+	palgo->VL53LX_p_019 = 0;
+	palgo->VL53LX_p_021 = 0;
+	palgo->VL53LX_p_039 = 0;
+	palgo->VL53LX_p_028 = 0;
+	palgo->VL53LX_p_031 = 0;
+
+	for (lb = palgo->VL53LX_p_019; lb < palgo->VL53LX_p_020; lb++) {
+		palgo->VL53LX_p_040[lb]     = 0;
+		palgo->VL53LX_p_041[lb]     = 0;
+		palgo->VL53LX_p_042[lb]     = 0;
+		palgo->VL53LX_p_043[lb]     = 0;
+		palgo->VL53LX_p_018[lb]     = 0;
+	}
+	palgo->VL53LX_p_044 = 0;
+	palgo->VL53LX_p_045 = VL53LX_D_001;
+	palgo->VL53LX_p_046 = 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 *pdata)
+{
+	uint8_t bin = 0;
+
+	for (bin = 0; bin < pdata->VL53LX_p_021; bin++) {
+		if (bin == 0 || pdata->min_bin_value >= pdata->bin_data[bin])
+			pdata->min_bin_value = pdata->bin_data[bin];
+
+		if (bin == 0 || pdata->max_bin_value <= pdata->bin_data[bin])
+			pdata->max_bin_value = pdata->bin_data[bin];
+	}
+}
+
+uint32_t VL53LX_isqrt(uint32_t num)
+{
+	uint32_t  res = 0;
+	uint32_t  bit = 1 << 30;
+
+	while (bit > num)
+		bit >>= 2;
+
+	while (bit != 0) {
+		if (num >= res + bit)  {
+			num -= res + bit;
+			res = (res >> 1) + bit;
+		} else {
+			res >>= 1;
+		}
+		bit >>= 2;
+	}
+
+	return res;
+}
+
+
+void VL53LX_hist_estimate_ambient_from_thresholded_bins(int32_t ambient_threshold_sigma, VL53LX_histogram_bin_data_t *pdata)
+{
+	uint8_t  bin                      = 0;
+	int32_t  VL53LX_p_031 = 0;
+
+	VL53LX_hist_find_min_max_bin_values(pdata);
+
+	VL53LX_p_031  = (int32_t)VL53LX_isqrt((uint32_t)pdata->min_bin_value);
+	VL53LX_p_031 *= ambient_threshold_sigma;
+	VL53LX_p_031 += 0x07;
+	VL53LX_p_031  = VL53LX_p_031 >> 4;
+	VL53LX_p_031 += pdata->min_bin_value;
+
+	pdata->number_of_ambient_samples = 0;
+	pdata->ambient_events_sum        = 0;
+
+	for (bin = 0; bin < pdata->VL53LX_p_021; bin++) {
+		if (pdata->bin_data[bin] < VL53LX_p_031) {
+			pdata->ambient_events_sum += pdata->bin_data[bin];
+			pdata->number_of_ambient_samples++;
+		}
+	}
+
+	if (pdata->number_of_ambient_samples > 0) {
+		pdata->VL53LX_p_028  = pdata->ambient_events_sum;
+		pdata->VL53LX_p_028 += ((int32_t)pdata->number_of_ambient_samples/2);
+		pdata->VL53LX_p_028 /= (int32_t)pdata->number_of_ambient_samples;
+	}
+}
+
+void VL53LX_hist_remove_ambient_bins(VL53LX_histogram_bin_data_t *pdata)
+{
+	uint8_t bin = 0;
+	uint8_t lc = 0;
+	uint8_t i = 0;
+
+	if ((pdata->bin_seq[0] & 0x07) == 0x07) {
+		i = 0;
+		for (lc = 0; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH; lc++) {
+			if ((pdata->bin_seq[lc] & 0x07) != 0x07) {
+				pdata->bin_seq[i] = pdata->bin_seq[lc];
+				pdata->bin_rep[i] = pdata->bin_rep[lc];
+				i++;
+			}
+		}
+		for (lc = i; lc < VL53LX_MAX_BIN_SEQUENCE_LENGTH; lc++) {
+			pdata->bin_seq[lc] = VL53LX_MAX_BIN_SEQUENCE_CODE + 1;
+			pdata->bin_rep[lc] = 0;
+		}
+	}
+	if (pdata->number_of_ambient_bins > 0) {
+		for (bin = pdata->number_of_ambient_bins; bin < pdata->VL53LX_p_020; bin++) {
+			pdata->bin_data[bin-pdata->number_of_ambient_bins] = pdata->bin_data[bin];
+		}
+		pdata->VL53LX_p_021 = pdata->VL53LX_p_021 - pdata->number_of_ambient_bins;
+		pdata->number_of_ambient_bins = 0;
+	}
+}
+
+int8_t VL53LX_f_030(VL53LX_histogram_bin_data_t *pdata1, VL53LX_histogram_bin_data_t *pdata2)
+{
+	int32_t  phase_delta      = 0;
+	int8_t   bin_offset       = 0;
+	uint32_t period           = 0;
+	uint32_t remapped_phase   = 0;
+
+	period = 2048 * (uint32_t)VL53LX_decode_vcsel_period(pdata1->VL53LX_p_005);
+
+	if (period != 0)
+		remapped_phase = (uint32_t)pdata2->zero_distance_phase % period;
+
+	phase_delta = (int32_t)pdata1->zero_distance_phase - (int32_t)remapped_phase;
+
+	if (phase_delta > 0)
+		bin_offset = (int8_t)((phase_delta + 1024) / 2048);
+	else
+		bin_offset = (int8_t)((phase_delta - 1024) / 2048);
+
+	return bin_offset;
+}
+
+void VL53LX_f_005(VL53LX_histogram_bin_data_t *pxtalk, VL53LX_histogram_bin_data_t *pbins, VL53LX_histogram_bin_data_t *pxtalk_realigned)
+{
+	uint8_t i          = 0;
+	uint8_t min_bins   = 0;
+	int8_t  bin_offset = 0;
+	int8_t  bin_access = 0;
+
+	memcpy(pxtalk_realigned, pbins, sizeof(VL53LX_histogram_bin_data_t));
+
+	for (i = 0 ; i < pxtalk_realigned->VL53LX_p_020 ; i++)
+		pxtalk_realigned->bin_data[i] = 0;
+
+	bin_offset = VL53LX_f_030(pbins, pxtalk);
+
+	if (pxtalk->VL53LX_p_021 < pbins->VL53LX_p_021)
+		min_bins = pxtalk->VL53LX_p_021;
+	else
+		min_bins = pbins->VL53LX_p_021;
+
+	for (i = 0 ; i <  min_bins ; i++) {
+		if (bin_offset >= 0)
+			bin_access = ((int8_t)i + (int8_t)bin_offset) % (int8_t)pbins->VL53LX_p_021;
+		else
+			bin_access = ((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] = pbins->bin_data[(uint8_t)bin_access] - pxtalk->bin_data[i];
+		} else {
+			pbins->bin_data[(uint8_t)bin_access] = 0;
+		}
+		pxtalk_realigned->bin_data[(uint8_t)bin_access] = pxtalk->bin_data[i];
+
+
+
+	}
+}
+
+uint16_t VL53LX_rate_maths(int32_t VL53LX_p_018, uint32_t time_us)
+{
+	uint32_t  tmp_int   = 0;
+	uint32_t  frac_bits = 7;
+	uint16_t  rate_mcps = 0;
+
+	if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_MAX)
+		tmp_int = VL53LX_SPAD_TOTAL_COUNT_MAX;
+	else if (VL53LX_p_018 > 0)
+		tmp_int = (uint32_t)VL53LX_p_018;
+
+	if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_RES_THRES)
+		frac_bits = 3;
+	else
+		frac_bits = 7;
+
+	if (time_us > 0)
+		tmp_int = ((tmp_int << frac_bits) + (time_us / 2)) / time_us;
+
+	if (VL53LX_p_018 > VL53LX_SPAD_TOTAL_COUNT_RES_THRES)
+		tmp_int = tmp_int << 4;
+
+	if (tmp_int > 0xFFFF)
+		tmp_int = 0xFFFF;
+
+	rate_mcps =  (uint16_t)tmp_int;
+	return rate_mcps;
+}
+
+uint32_t VL53LX_events_per_spad_maths(int32_t VL53LX_p_010, uint16_t num_spads, uint32_t duration)
+{
+	uint64_t total_hist_counts  = 0;
+	uint64_t xtalk_per_spad     = 0;
+	uint32_t rate_per_spad_kcps = 0;
+	uint64_t dividend = ((uint64_t)VL53LX_p_010 * 1000 * 256);
+
+	if (num_spads != 0)
+		total_hist_counts = do_division_u(dividend, (uint64_t)num_spads);
+
+	if (duration > 0) {
+		uint64_t dividend = (((uint64_t)(total_hist_counts << 11)) + ((uint64_t)duration / 2));
+		xtalk_per_spad = do_division_u(dividend, (uint64_t)duration);
+	} else {
+		xtalk_per_spad = (uint64_t)(total_hist_counts << 11);
+	}
+	rate_per_spad_kcps = (uint32_t)xtalk_per_spad;
+	return rate_per_spad_kcps;
+}
+
+uint32_t VL53LX_f_002(uint32_t events_threshold, uint32_t ref_signal_events, uint32_t ref_distance_mm, uint32_t signal_thresh_sigma)
+{
+	uint32_t    tmp32               = 0;
+	uint32_t    range_mm            = 0;
+
+	tmp32 = 4 * events_threshold;
+	tmp32 += ((uint32_t)signal_thresh_sigma * (uint32_t)signal_thresh_sigma);
+	tmp32  = VL53LX_isqrt(tmp32);
+	tmp32 += (uint32_t)signal_thresh_sigma;
+
+	range_mm = (uint32_t)VL53LX_isqrt(ref_signal_events << 4);
+	range_mm *= ref_distance_mm;
+	if (tmp32 != 0) {
+		range_mm += (tmp32);
+		range_mm /= (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  = VL53LX_ERROR_NONE;
+	uint32_t    pll_period_us       = 0;
+	uint32_t    periods_elapsed     = 0;
+	uint32_t    tmp32               = 0;
+	uint64_t    tmp64               = 0;
+	uint32_t    amb_thres_delta     = 0;
+
+	pdata->VL53LX_p_004 = 0x0000;
+	pdata->VL53LX_p_033 = 0x0000;
+	pdata->VL53LX_p_034 = 0x0000;
+	pdata->VL53LX_p_009 = 0x0000;
+	pdata->VL53LX_p_028 = 0x0000;
+	pdata->VL53LX_p_035 = 0x0000;
+	pdata->VL53LX_p_036 = 0;
+	pdata->VL53LX_p_022 = 0;
+	*pambient_dmax_mm   = 0;
+
+	if ((pbins->VL53LX_p_015 != 0) && (pbins->total_periods_elapsed != 0)) {
+		pll_period_us = VL53LX_calc_pll_period_us(pbins->VL53LX_p_015);
+		periods_elapsed = pbins->total_periods_elapsed + 1;
+		pdata->VL53LX_p_037 = VL53LX_duration_maths(pll_period_us, 1<<4, VL53LX_RANGING_WINDOW_VCSEL_PERIODS, periods_elapsed);
+		pdata->VL53LX_p_034 = VL53LX_rate_maths(pbins->VL53LX_p_028, pdata->VL53LX_p_037);
+		pdata->VL53LX_p_033 = VL53LX_events_per_spad_maths(pbins->VL53LX_p_028, pbins->result__dss_actual_effective_spads, pdata->VL53LX_p_037);
+		pdata->VL53LX_p_038 = pcfg->max_effective_spads;
+		pdata->VL53LX_p_004  = pcfg->max_effective_spads;
+
+		if (pdata->VL53LX_p_033 > 0) {
+			tmp64   = (uint64_t)pcfg->dss_config__target_total_rate_mcps;
+			tmp64  *= 1000;
+			tmp64 <<= (11+1);
+			tmp32  = pdata->VL53LX_p_033/2;
+			tmp64 += (uint64_t)tmp32;
+			tmp64 = do_division_u(tmp64, (uint64_t)pdata->VL53LX_p_033);
+			if (tmp64 < (uint64_t)pcfg->max_effective_spads)
+				pdata->VL53LX_p_004 = (uint16_t)tmp64;
+		}
+	}
+	if ((pcal->ref__actual_effective_spads != 0) && (pbins->VL53LX_p_015 != 0) && (pcal->ref_reflectance_pc != 0) && (pbins->total_periods_elapsed != 0)) {
+		tmp64  = (uint64_t)pcal->ref__peak_signal_count_rate_mcps;
+		tmp64 *= (1000 * 256);
+		tmp32  = pcal->ref__actual_effective_spads/2;
+		tmp64 += (uint64_t)tmp32;
+		tmp64  = do_division_u(tmp64, (uint64_t)pcal->ref__actual_effective_spads);
+
+		pdata->VL53LX_p_009   = (uint32_t)tmp64;
+		pdata->VL53LX_p_009 <<= 4;
+
+		tmp64   = (uint64_t)pdata->VL53LX_p_037;
+		tmp64  *= (uint64_t)pdata->VL53LX_p_033;
+		tmp64  *= (uint64_t)pdata->VL53LX_p_004;
+		tmp64  += (1<<(11+7));
+		tmp64 >>= (11+8);
+		tmp64  +=  500;
+		tmp64   = do_division_u(tmp64, 1000);
+
+		if (tmp64 > 0x00FFFFFF)
+			tmp64 = 0x00FFFFFF;
+
+		pdata->VL53LX_p_028 = (uint32_t)tmp64;
+		tmp64   = (uint64_t)pdata->VL53LX_p_037;
+		tmp64  *= (uint64_t)pdata->VL53LX_p_009;
+		tmp64  *= (uint64_t)pdata->VL53LX_p_004;
+		tmp64  += (1<<(11+7));
+		tmp64 >>= (11+8);
+		tmp64  *= ((uint64_t)target_reflectance * (uint64_t)pcal->coverglass_transmission);
+		tmp64  += ((uint64_t)pcal->ref_reflectance_pc * 128);
+		tmp64  = do_division_u(tmp64, ((uint64_t)pcal->ref_reflectance_pc * 256));
+		tmp64  +=  500;
+		tmp64  = do_division_u(tmp64, 1000);
+		if (tmp64 > 0x00FFFFFF)
+			tmp64 = 0x00FFFFFF;
+		pdata->VL53LX_p_035 = (uint32_t)tmp64;
+		tmp32  = VL53LX_isqrt(pdata->VL53LX_p_028 << 8);
+		tmp32 *= (uint32_t)pcfg->ambient_thresh_sigma;
+		if (pdata->VL53LX_p_028 < (uint32_t)pcfg->min_ambient_thresh_events) {
+			amb_thres_delta = pcfg->min_ambient_thresh_events - (uint32_t)pdata->VL53LX_p_028;
+			amb_thres_delta <<= 8;
+			if (tmp32 < amb_thres_delta)
+				tmp32 = amb_thres_delta;
+		}
+		pdata->VL53LX_p_022 = (int16_t)VL53LX_f_002(tmp32, pdata->VL53LX_p_035, (uint32_t)pcal->ref__distance_mm, (uint32_t)pcfg->signal_thresh_sigma);
+
+		tmp32  = (uint32_t)pdata->VL53LX_p_035;
+		tmp32 *= (uint32_t)pbins->vcsel_width;
+		tmp32 += (1 << 3);
+		tmp32 /= (1 << 4);
+
+		pdata->VL53LX_p_036 = (int16_t)VL53LX_f_002(256 * (uint32_t)pcfg->signal_total_events_limit, tmp32, (uint32_t)pcal->ref__distance_mm, (uint32_t)pcfg->signal_thresh_sigma);
+
+		if (pdata->VL53LX_p_036 < pdata->VL53LX_p_022)
+			*pambient_dmax_mm = pdata->VL53LX_p_036;
+		else
+			*pambient_dmax_mm = 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  = VL53LX_ERROR_NONE;
+	uint8_t  lb            = 0;
+	uint8_t  VL53LX_p_001            = 0;
+	int64_t  tmp          = 0;
+	int32_t  amb_events   = 0;
+	int32_t  VL53LX_p_018       = 0;
+	int32_t  samples      = 0;
+
+	palgo->VL53LX_p_020 = pbins->VL53LX_p_020;
+	palgo->VL53LX_p_019 = pbins->VL53LX_p_019;
+	palgo->VL53LX_p_021 = pbins->VL53LX_p_021;
+	palgo->VL53LX_p_028 = pbins->VL53LX_p_028;
+	palgo->VL53LX_p_030 = VL53LX_decode_vcsel_period(pbins->VL53LX_p_005);
+
+	tmp  = (int64_t)pbins->VL53LX_p_028;
+	tmp *= (int64_t)ambient_threshold_events_scaler;
+	tmp += 2048;
+	tmp  = do_division_s(tmp, 4096);
+	amb_events = (int32_t)tmp;
+
+	for (lb = 0; lb < pbins->VL53LX_p_021; lb++) {
+		VL53LX_p_001 = lb >> 2;
+		samples = (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 = samples * (amb_events + pxtalk->bin_data[lb]);
+			else
+				VL53LX_p_018 = samples *  amb_events;
+			VL53LX_p_018  = VL53LX_isqrt(VL53LX_p_018);
+			VL53LX_p_018 += (samples/2);
+			VL53LX_p_018 /= samples;
+			VL53LX_p_018 *= ambient_threshold_sigma;
+			VL53LX_p_018 += 8;
+			VL53LX_p_018 /= 16;
+			VL53LX_p_018 += amb_events;
+			if (VL53LX_p_018 < min_ambient_threshold_events)
+				VL53LX_p_018 = min_ambient_threshold_events;
+			palgo->VL53LX_p_052[lb]             = VL53LX_p_018;
+			palgo->VL53LX_p_031 = VL53LX_p_018;
+		}
+	}
+	palgo->VL53LX_p_039 = 0;
+	for (lb = 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] = 1;
+			palgo->VL53LX_p_041[lb] = 1;
+			palgo->VL53LX_p_039++;
+		} else {
+			palgo->VL53LX_p_040[lb] = 0;
+			palgo->VL53LX_p_041[lb] = 0;
+		}
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_f_007(VL53LX_hist_gen3_algo_private_data_t *palgo)
+{
+	VL53LX_Error  status  = VL53LX_ERROR_NONE;
+	uint8_t  i            = 0;
+	uint8_t  j            = 0;
+	uint8_t  found        = 0;
+
+	palgo->VL53LX_p_044 = 0;
+	for (i = 0; i < palgo->VL53LX_p_030; i++) {
+		j = (i + 1) % palgo->VL53LX_p_030;
+		if (i < palgo->VL53LX_p_021 && j < palgo->VL53LX_p_021) {
+			if (palgo->VL53LX_p_041[i] == 0 && palgo->VL53LX_p_041[j] == 1 && found == 0) {
+				palgo->VL53LX_p_044 = i;
+				found = 1;
+			}
+		}
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_f_008(VL53LX_hist_gen3_algo_private_data_t *palgo)
+{
+	VL53LX_Error  status  = VL53LX_ERROR_NONE;
+	uint8_t  i            = 0;
+	uint8_t  j            = 0;
+	uint8_t  lb            = 0;
+
+	for (lb = palgo->VL53LX_p_044; lb < (palgo->VL53LX_p_044 + palgo->VL53LX_p_030); lb++) {
+		i =  lb      % palgo->VL53LX_p_030;
+		j = (lb + 1) % palgo->VL53LX_p_030;
+		if (i < palgo->VL53LX_p_021 && j < palgo->VL53LX_p_021) {
+			if (palgo->VL53LX_p_041[i] == 0 && palgo->VL53LX_p_041[j] == 1)
+				palgo->VL53LX_p_046++;
+			if (palgo->VL53LX_p_046 > palgo->VL53LX_p_045)
+				palgo->VL53LX_p_046 = palgo->VL53LX_p_045;
+			if (palgo->VL53LX_p_041[i] > 0)
+				palgo->VL53LX_p_042[i] = palgo->VL53LX_p_046;
+			else
+				palgo->VL53LX_p_042[i] = 0;
+		}
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_f_009(VL53LX_hist_gen3_algo_private_data_t *palgo)
+{
+	VL53LX_Error  status  = VL53LX_ERROR_NONE;
+
+	uint8_t  i            = 0;
+	uint8_t  j            = 0;
+	uint8_t  blb            = 0;
+	uint8_t  pulse_no     = 0;
+	uint8_t  max_filter_half_width = 0;
+	VL53LX_hist_pulse_data_t *pdata;
+
+	max_filter_half_width = palgo->VL53LX_p_030 - 1;
+	max_filter_half_width = max_filter_half_width >> 1;
+
+	for (blb = palgo->VL53LX_p_044; blb < (palgo->VL53LX_p_044 + palgo->VL53LX_p_030); blb++) {
+		i =  blb      % palgo->VL53LX_p_030;
+		j = (blb + 1) % palgo->VL53LX_p_030;
+
+		if (i < palgo->VL53LX_p_021 && j < palgo->VL53LX_p_021) {
+			if (palgo->VL53LX_p_042[i] == 0 && palgo->VL53LX_p_042[j] > 0) {
+				pulse_no = palgo->VL53LX_p_042[j] - 1;
+				if (pulse_no < palgo->VL53LX_p_045) {
+					pdata = &(palgo->VL53LX_p_003[pulse_no]);
+					pdata->VL53LX_p_012 = blb;
+					pdata->VL53LX_p_019    = blb + 1;
+					pdata->VL53LX_p_023   = 0xFF;
+					pdata->VL53LX_p_024     = 0;
+					pdata->VL53LX_p_013   = 0;
+				}
+			}
+			if (palgo->VL53LX_p_042[i] > 0 && palgo->VL53LX_p_042[j] == 0) {
+				pulse_no = palgo->VL53LX_p_042[i] - 1;
+				if (pulse_no < palgo->VL53LX_p_045) {
+					pdata = &(palgo->VL53LX_p_003[pulse_no]);
+					pdata->VL53LX_p_024 = blb;
+					pdata->VL53LX_p_013 = blb + 1;
+					pdata->VL53LX_p_025 = (pdata->VL53LX_p_024 + 1) - pdata->VL53LX_p_019;
+					pdata->VL53LX_p_051 = (pdata->VL53LX_p_013 + 1) - pdata->VL53LX_p_012;
+					if (pdata->VL53LX_p_051 > max_filter_half_width)
+						pdata->VL53LX_p_051 = max_filter_half_width;
+				}
+			}
+		}
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_f_010(uint8_t pulse_no, VL53LX_histogram_bin_data_t *pbins, VL53LX_hist_gen3_algo_private_data_t *palgo)
+{
+	VL53LX_Error  status  = VL53LX_ERROR_NONE;
+	uint8_t  i            = 0;
+	uint8_t  lb            = 0;
+
+	VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]);
+	pdata->VL53LX_p_017  = 0;
+	pdata->VL53LX_p_016 = 0;
+
+	for (lb = pdata->VL53LX_p_012; lb <= pdata->VL53LX_p_013; lb++) {
+		i =  lb % palgo->VL53LX_p_030;
+		pdata->VL53LX_p_017 += pbins->bin_data[i];
+		pdata->VL53LX_p_016 += palgo->VL53LX_p_028;
+	}
+	pdata->VL53LX_p_010 = 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  = VL53LX_ERROR_NONE;
+
+	uint8_t  i            = 0;
+	uint8_t  lb            = 0;
+	VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]);
+
+	memcpy(ppulse, pbins, sizeof(VL53LX_histogram_bin_data_t));
+
+	for (lb = palgo->VL53LX_p_044; lb < (palgo->VL53LX_p_044 + palgo->VL53LX_p_030); lb++) {
+		if (lb < pdata->VL53LX_p_012 || lb > pdata->VL53LX_p_013) {
+			i =  lb % palgo->VL53LX_p_030;
+			if (i < ppulse->VL53LX_p_021)
+				ppulse->bin_data[i] = pad_value;
+		}
+	}
+	return status;
+}
+
+void VL53LX_f_022(uint8_t VL53LX_p_032, uint8_t filter_woi, VL53LX_histogram_bin_data_t *pbins, int32_t *pa, int32_t *pb, int32_t *pc)
+{
+	uint8_t w = 0;
+	uint8_t j = 0;
+
+	*pa = 0;
+	*pb = pbins->bin_data[VL53LX_p_032];
+	*pc = 0;
+
+	for (w = 0 ; w < ((filter_woi << 1)+1) ; w++) {
+		j = ((VL53LX_p_032 + w + pbins->VL53LX_p_021) - filter_woi) % pbins->VL53LX_p_021;
+		if (w < filter_woi)
+			*pa += pbins->bin_data[j];
+		else if (w > filter_woi)
+			*pc += 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       = VL53LX_ERROR_NONE;
+	VL53LX_hist_pulse_data_t *pdata = &(palgo3->VL53LX_p_003[pulse_no]);
+
+	uint8_t  lb    = 0;
+	uint8_t  i     = 0;
+	int32_t  suma  = 0;
+	int32_t  sumb  = 0;
+	int32_t  sumc  = 0;
+
+	pfiltered->VL53LX_p_020 = palgo3->VL53LX_p_020;
+	pfiltered->VL53LX_p_019 = palgo3->VL53LX_p_019;
+	pfiltered->VL53LX_p_021 = palgo3->VL53LX_p_021;
+
+	for (lb = pdata->VL53LX_p_012; lb <= pdata->VL53LX_p_013; lb++) {
+		i = lb % palgo3->VL53LX_p_030;
+		VL53LX_f_022(i, pdata->VL53LX_p_051, ppulse, &suma, &sumb, &sumc);
+
+		pfiltered->VL53LX_p_007[i] = suma;
+		pfiltered->VL53LX_p_032[i] = sumb;
+		pfiltered->VL53LX_p_001[i] = sumc;
+		pfiltered->VL53LX_p_053[i] = (suma + sumb) - (sumc + palgo3->VL53LX_p_028);
+		pfiltered->VL53LX_p_054[i] = (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 = VL53LX_ERROR_DIVISION_BY_ZERO;
+
+	int64_t  mean_phase  = VL53LX_MAX_ALLOWED_PHASE;
+	int32_t  mean_phase32;
+	int64_t  VL53LX_p_055   = 0;
+	int64_t  half_b_minus_amb = 0;
+
+	VL53LX_p_055     = 4096 * ((int64_t)VL53LX_p_001 - (int64_t)cx - (int64_t)VL53LX_p_007 -  (int64_t)ax);
+	half_b_minus_amb = 4096 * ((int64_t)VL53LX_p_032 - (int64_t)bx - (int64_t)VL53LX_p_028);
+
+	if (half_b_minus_amb != 0) {
+		mean_phase = (4096 * VL53LX_p_055) + half_b_minus_amb;
+		mean_phase = do_division_s(mean_phase, (half_b_minus_amb * 2));
+		mean_phase  +=  2048;
+		mean_phase  += (4096 * (int64_t)bin);
+		mean_phase  = do_division_s((mean_phase + 1), 2);
+		if (mean_phase  < 0)
+			mean_phase = 0;
+		if (mean_phase > VL53LX_MAX_ALLOWED_PHASE)
+			mean_phase = VL53LX_MAX_ALLOWED_PHASE;
+		mean_phase32 = (int32_t)mean_phase;
+		mean_phase32 = mean_phase32 % ((int32_t)VL53LX_p_030 * 2048);
+		mean_phase = mean_phase32;
+		status = VL53LX_ERROR_NONE;
+	}
+	*pmean_phase = (uint32_t)mean_phase;
+	return status;
+}
+
+VL53LX_Error VL53LX_f_027(uint8_t pulse_no, uint16_t noise_threshold, VL53LX_hist_gen4_algo_filtered_data_t *pfiltered, VL53LX_hist_gen3_algo_private_data_t *palgo3)
+{
+	VL53LX_Error  status       = VL53LX_ERROR_NONE;
+	VL53LX_Error  func_status  = VL53LX_ERROR_NONE;
+	VL53LX_hist_pulse_data_t *pdata = &(palgo3->VL53LX_p_003[pulse_no]);
+
+	uint8_t  lb            = 0;
+	uint8_t  i            = 0;
+	uint8_t  j            = 0;
+
+	for (lb = pdata->VL53LX_p_012; lb < pdata->VL53LX_p_013; lb++) {
+		i =  lb    % palgo3->VL53LX_p_030;
+		j = (lb+1) % palgo3->VL53LX_p_030;
+		if (i < palgo3->VL53LX_p_021 && j < palgo3->VL53LX_p_021) {
+			if (pfiltered->VL53LX_p_053[i] == 0 && pfiltered->VL53LX_p_054[i] == 0)
+				pfiltered->VL53LX_p_040[i] = 0;
+			else if (pfiltered->VL53LX_p_053[i] >= 0 && pfiltered->VL53LX_p_054[i] >= 0)
+				pfiltered->VL53LX_p_040[i] = 1;
+			else if (pfiltered->VL53LX_p_053[i] <  0 && pfiltered->VL53LX_p_054[i] >= 0 && pfiltered->VL53LX_p_053[j] >= 0 && pfiltered->VL53LX_p_054[j] <  0)
+				pfiltered->VL53LX_p_040[i] = 1;
+			else
+				pfiltered->VL53LX_p_040[i] = 0;
+
+			if (pfiltered->VL53LX_p_040[i] > 0) {
+				pdata->VL53LX_p_023 = lb;
+				func_status =
+					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 ==
+					VL53LX_ERROR_DIVISION_BY_ZERO)
+					pfiltered->VL53LX_p_040[i] = 0;
+
+			}
+		}
+	}
+	return status;
+}
+
+uint32_t VL53LX_calc_pll_period_mm(uint16_t fast_osc_frequency)
+{
+	uint32_t pll_period_us = 0;
+	uint32_t pll_period_mm = 0;
+
+	pll_period_us  = VL53LX_calc_pll_period_us(fast_osc_frequency);
+	pll_period_mm = VL53LX_SPEED_OF_LIGHT_IN_AIR_DIV_8 * (pll_period_us >> 2);
+	pll_period_mm = (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 = VL53LX_ERROR_DIVISION_BY_ZERO;
+	uint32_t sigma_int  = VL53LX_D_002;
+	uint32_t pll_period_mm  = 0;
+	uint64_t tmp0        = 0;
+	uint64_t tmp1        = 0;
+	uint64_t b_minus_amb = 0;
+	uint64_t VL53LX_p_055   = 0;
+	*psigma_est  = VL53LX_D_002;
+	if (fast_osc_frequency != 0) {
+		pll_period_mm = VL53LX_calc_pll_period_mm(fast_osc_frequency);
+
+		if (VL53LX_p_028 > VL53LX_p_032)
+			b_minus_amb = (uint64_t)VL53LX_p_028 - (uint64_t)VL53LX_p_032;
+		else
+			b_minus_amb =  (uint64_t)VL53LX_p_032 - (uint64_t)VL53LX_p_028;
+
+		if (VL53LX_p_007 > VL53LX_p_001)
+			VL53LX_p_055 =  (uint64_t)VL53LX_p_007 - (uint64_t)VL53LX_p_001;
+		else
+			VL53LX_p_055 =  (uint64_t)VL53LX_p_001 - (uint64_t)VL53LX_p_007;
+
+		if (b_minus_amb != 0) {
+			tmp0 = (uint64_t)VL53LX_p_032 + (uint64_t)bx + (uint64_t)VL53LX_p_028;
+			if (tmp0 > VL53LX_D_003)
+				tmp0 = VL53LX_D_003;
+
+			tmp1 = (uint64_t)VL53LX_p_055 * (uint64_t)VL53LX_p_055;
+			tmp1 = tmp1 << 8;
+
+			if (tmp1 > VL53LX_D_004)
+				tmp1 = VL53LX_D_004;
+
+			tmp1 = do_division_u(tmp1, b_minus_amb);
+			tmp1 = do_division_u(tmp1, b_minus_amb);
+
+			if (tmp1 > (uint64_t)VL53LX_D_005)
+				tmp1 = (uint64_t)VL53LX_D_005;
+
+			tmp0 = tmp1 * tmp0;
+			tmp1 = (uint64_t)c_zp + (uint64_t)cx_zp + (uint64_t)a_zp + (uint64_t)ax_zp;
+
+			if (tmp1 > (uint64_t)VL53LX_D_003)
+				tmp1 = (uint64_t)VL53LX_D_003;
+
+			tmp1 = tmp1 << 8;
+
+			tmp0 = tmp1 + tmp0;
+			if (tmp0 > (uint64_t)VL53LX_D_006)
+				tmp0 = (uint64_t)VL53LX_D_006;
+
+			if (tmp0 > (uint64_t)VL53LX_D_007) {
+				tmp0 = do_division_u(tmp0, b_minus_amb);
+				tmp0 = tmp0 * pll_period_mm;
+			} else {
+				tmp0 = tmp0 * pll_period_mm;
+				tmp0 = do_division_u(tmp0, b_minus_amb);
+			}
+
+			if (tmp0 > (uint64_t)VL53LX_D_006)
+				tmp0 = (uint64_t)VL53LX_D_006;
+
+			if (tmp0 > (uint64_t)VL53LX_D_007) {
+				tmp0 = do_division_u(tmp0, b_minus_amb);
+				tmp0 = do_division_u(tmp0, 4);
+				tmp0 = tmp0 * pll_period_mm;
+			} else {
+				tmp0 = tmp0 * pll_period_mm;
+				tmp0 = do_division_u(tmp0, b_minus_amb);
+				tmp0 = do_division_u(tmp0, 4);
+			}
+
+			if (tmp0 > (uint64_t)VL53LX_D_006)
+				tmp0 = (uint64_t)VL53LX_D_006;
+
+			tmp0 = tmp0 >> 2;
+
+			if (tmp0 > (uint64_t)VL53LX_D_007)
+				tmp0 = (uint64_t)VL53LX_D_007;
+
+			tmp1 = (uint64_t)sigma_estimator__sigma_ref_mm << 7;
+			tmp1 = tmp1 * tmp1;
+			tmp0 = tmp0 + tmp1;
+
+			if (tmp0 > (uint64_t)VL53LX_D_007)
+				tmp0 = (uint64_t)VL53LX_D_007;
+
+			sigma_int = VL53LX_isqrt((uint32_t)tmp0);
+			*psigma_est = (uint16_t)sigma_int;
+			status = 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      = VL53LX_ERROR_NONE;
+	VL53LX_Error func_status = VL53LX_ERROR_NONE;
+
+	uint8_t  i    = 0;
+	int32_t  VL53LX_p_007    = 0;
+	int32_t  VL53LX_p_032    = 0;
+	int32_t  VL53LX_p_001    = 0;
+	int32_t  a_zp = 0;
+	int32_t  c_zp = 0;
+	int32_t  ax   = 0;
+	int32_t  bx   = 0;
+	int32_t  cx   = 0;
+
+	if (VL53LX_p_030 == 0) {
+		*psigma_est = 0xFFFF;
+		return VL53LX_ERROR_DIVISION_BY_ZERO;
+	}
+	i = 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 =
+		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 == VL53LX_ERROR_DIVISION_BY_ZERO)
+		*psigma_est = 0xFFFF;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_f_020(int16_t VL53LX_p_019, int16_t VL53LX_p_024, uint8_t VL53LX_p_030, uint8_t clip_events, VL53LX_histogram_bin_data_t *pbins, uint32_t *pphase)
+{
+	VL53LX_Error  status  = VL53LX_ERROR_NONE;
+	int16_t  i            = 0;
+	int16_t  lb            = 0;
+	int64_t VL53LX_p_018        = 0;
+	int64_t event_sum     = 0;
+	int64_t weighted_sum  = 0;
+
+	*pphase = VL53LX_MAX_ALLOWED_PHASE;
+
+	if (VL53LX_p_030 != 0) {
+		for (lb = VL53LX_p_019; lb <= VL53LX_p_024; lb++) {
+			if (lb < 0)
+				i = lb + (int16_t)VL53LX_p_030;
+			else
+				i = lb % (int16_t)VL53LX_p_030;
+
+			if ((i >= 0) && (i < VL53LX_HISTOGRAM_BUFFER_SIZE)) {
+				VL53LX_p_018 = (int64_t)pbins->bin_data[i] - (int64_t)pbins->VL53LX_p_028;
+
+				if (clip_events > 0 && VL53LX_p_018 < 0)
+					VL53LX_p_018 = 0;
+				event_sum += VL53LX_p_018;
+				weighted_sum += (VL53LX_p_018 * (1024 + (2048*(int64_t)lb)));
+			}
+
+		}
+		if (event_sum > 0) {
+			weighted_sum += do_division_s(event_sum, 2);
+			weighted_sum = do_division_s(weighted_sum, event_sum);
+			if (weighted_sum < 0)
+				weighted_sum = 0;
+			*pphase = (uint32_t)weighted_sum;
+		}
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_f_015(uint8_t pulse_no, uint8_t clip_events, VL53LX_histogram_bin_data_t *pbins, VL53LX_hist_gen3_algo_private_data_t *palgo)
+{
+	VL53LX_Error  status  = VL53LX_ERROR_NONE;
+	uint8_t   i            = 0;
+	int16_t   VL53LX_p_012 = 0;
+	int16_t   VL53LX_p_013   = 0;
+	int16_t   window_width = 0;
+	uint32_t  tmp_phase    = 0;
+
+	VL53LX_hist_pulse_data_t *pdata = &(palgo->VL53LX_p_003[pulse_no]);
+
+	if (pdata->VL53LX_p_023 == 0xFF)
+		pdata->VL53LX_p_023 = 1;
+
+	i = pdata->VL53LX_p_023 % palgo->VL53LX_p_030;
+
+	VL53LX_p_012  = (int16_t)i;
+	VL53LX_p_012 += (int16_t)pdata->VL53LX_p_012;
+	VL53LX_p_012 -= (int16_t)pdata->VL53LX_p_023;
+
+	VL53LX_p_013  = (int16_t)i;
+	VL53LX_p_013 += (int16_t)pdata->VL53LX_p_013;
+	VL53LX_p_013 -= (int16_t)pdata->VL53LX_p_023;
+
+	window_width = VL53LX_p_013 - VL53LX_p_012;
+	if (window_width > 3)
+		window_width = 3;
+
+	status = VL53LX_f_020(VL53LX_p_012, VL53LX_p_012 + window_width, palgo->VL53LX_p_030, clip_events, pbins, &(pdata->VL53LX_p_026));
+
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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 = pdata->VL53LX_p_026;
+		pdata->VL53LX_p_026 = pdata->VL53LX_p_027;
+		pdata->VL53LX_p_027 = tmp_phase;
+	}
+
+	if (pdata->VL53LX_p_011 < pdata->VL53LX_p_026)
+		pdata->VL53LX_p_026 = pdata->VL53LX_p_011;
+
+	if (pdata->VL53LX_p_011 > pdata->VL53LX_p_027)
+		pdata->VL53LX_p_027 = 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  = VL53LX_ERROR_NONE;
+
+	VL53LX_hist_pulse_data_t  tmp;
+	VL53LX_hist_pulse_data_t *ptmp = &tmp;
+	VL53LX_hist_pulse_data_t *p0;
+	VL53LX_hist_pulse_data_t *p1;
+
+	uint8_t i       = 0;
+	uint8_t swapped = 1;
+
+	if (!(palgo->VL53LX_p_046 > 1))
+		goto ENDFUNC;
+
+	while (swapped > 0) {
+		swapped = 0;
+		for (i = 1; i < palgo->VL53LX_p_046; i++) {
+			p0 = &(palgo->VL53LX_p_003[i-1]);
+			p1 = &(palgo->VL53LX_p_003[i]);
+
+			if (target_order == 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 = 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 = 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 = 0;
+	uint16_t  upper_phase_limit = 0;
+
+	pdata->range_id     = range_id;
+	pdata->time_stamp   = 0;
+	pdata->VL53LX_p_012 = ppulse->VL53LX_p_012;
+	pdata->VL53LX_p_019 = ppulse->VL53LX_p_019;
+	pdata->VL53LX_p_023 = ppulse->VL53LX_p_023;
+	pdata->VL53LX_p_024 = ppulse->VL53LX_p_024;
+	pdata->VL53LX_p_013 = ppulse->VL53LX_p_013;
+	pdata->VL53LX_p_025 = ppulse->VL53LX_p_025;
+	pdata->VL53LX_p_029 = (ppulse->VL53LX_p_013 + 1) - ppulse->VL53LX_p_012;
+
+	pdata->zero_distance_phase   = pbins->zero_distance_phase;
+	pdata->VL53LX_p_002 = ppulse->VL53LX_p_002;
+	pdata->VL53LX_p_026 = (uint16_t)ppulse->VL53LX_p_026;
+	pdata->VL53LX_p_011 = (uint16_t)ppulse->VL53LX_p_011;
+	pdata->VL53LX_p_027 = (uint16_t)ppulse->VL53LX_p_027;
+	pdata->VL53LX_p_017 = (uint32_t)ppulse->VL53LX_p_017;
+	pdata->VL53LX_p_010 = ppulse->VL53LX_p_010;
+	pdata->VL53LX_p_016 = (uint32_t)ppulse->VL53LX_p_016;
+	pdata->total_periods_elapsed = pbins->total_periods_elapsed;
+
+	pdata->range_status = VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK;
+
+	if (sigma_thres > 0 && (uint32_t)ppulse->VL53LX_p_002 > ((uint32_t)sigma_thres << 5))
+		pdata->range_status = VL53LX_DEVICEERROR_SIGMATHRESHOLDCHECK;
+
+	lower_phase_limit = (uint8_t)valid_phase_low << 8;
+	if (lower_phase_limit < pdata->zero_distance_phase)
+		lower_phase_limit = pdata->zero_distance_phase - lower_phase_limit;
+	else
+		lower_phase_limit = 0;
+
+	upper_phase_limit  = (uint8_t)valid_phase_high << 8;
+	upper_phase_limit += pbins->zero_distance_phase;
+
+	if (pdata->VL53LX_p_011 < lower_phase_limit ||
+		pdata->VL53LX_p_011 > upper_phase_limit)
+		pdata->range_status = 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 = 0;
+	int64_t     tmp_long_int  = 0;
+	int32_t     range_mm      = 0;
+	int32_t     range_mm_10   = 0;
+
+	pll_period_us  = VL53LX_calc_pll_period_us(fast_osc_frequency);
+
+	tmp_long_int = (int64_t)VL53LX_p_014 - (int64_t)zero_distance_phase;
+	tmp_long_int =  tmp_long_int * (int64_t)pll_period_us;
+	tmp_long_int =  tmp_long_int / (0x01 << 9);
+	tmp_long_int =  tmp_long_int * VL53LX_SPEED_OF_LIGHT_IN_AIR_DIV_8;
+	tmp_long_int =  tmp_long_int / (0x01 << 22);
+
+	range_mm  = (int32_t)tmp_long_int + range_offset_mm;
+	range_mm *= gain_factor;
+	range_mm += 0x0400;
+	range_mm /= 0x0800;
+
+	if (fractional_bits == 0) {
+		range_mm_10 = range_mm * 10;
+		range_mm_10 = range_mm_10 / (0x01 << 2);
+		if ((range_mm_10 % 10) < 5)
+			range_mm = (int16_t)(range_mm_10 / 10);
+		else
+			range_mm = (int16_t)(range_mm_10 / 10 + 1);
+	} else if (fractional_bits == 1)
+		range_mm = range_mm / (0x01 << 1);
+	return range_mm;
+}
+
+void VL53LX_f_019(uint16_t gain_factor, int16_t range_offset_mm, VL53LX_range_data_t *pdata)
+{
+	pdata->min_range_mm =
+		(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 =
+		(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 =
+		(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_count_rate, uint16_t num_spads, uint32_t max_output_value)
+{
+	uint32_t  tmp_int   = 0;
+	uint16_t  rate_per_spad = 0;
+
+	if (num_spads > 0) {
+		tmp_int = (peak_count_rate << 8) << frac_bits;
+		tmp_int = (tmp_int + ((uint32_t)num_spads / 2)) / (uint32_t)num_spads;
+	} else {
+		tmp_int = ((peak_count_rate) << frac_bits);
+	}
+
+	if (tmp_int > max_output_value)
+		tmp_int = max_output_value;
+
+	rate_per_spad = (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 = VL53LX_ERROR_NONE;
+
+	uint32_t    pll_period_us       = 0;
+	uint32_t    periods_elapsed     = 0;
+	uint32_t    count_rate_total    = 0;
+
+	pdata->width                  = vcsel_width;
+	pdata->fast_osc_frequency     = fast_osc_frequency;
+	pdata->total_periods_elapsed  = total_periods_elapsed;
+	pdata->VL53LX_p_004 = VL53LX_p_004;
+
+	if (pdata->fast_osc_frequency == 0)
+		status = VL53LX_ERROR_DIVISION_BY_ZERO;
+
+	if (pdata->total_periods_elapsed == 0)
+		status = VL53LX_ERROR_DIVISION_BY_ZERO;
+
+	if (status == VL53LX_ERROR_NONE) {
+		pll_period_us = VL53LX_calc_pll_period_us(pdata->fast_osc_frequency);
+
+		periods_elapsed      = pdata->total_periods_elapsed + 1;
+
+		pdata->peak_duration_us    = VL53LX_duration_maths(pll_period_us, (uint32_t)pdata->width, VL53LX_RANGING_WINDOW_VCSEL_PERIODS, periods_elapsed);
+
+		pdata->woi_duration_us     = VL53LX_duration_maths(pll_period_us, ((uint32_t)pdata->VL53LX_p_029) << 4, VL53LX_RANGING_WINDOW_VCSEL_PERIODS, periods_elapsed);
+
+		pdata->peak_signal_count_rate_mcps = VL53LX_rate_maths((int32_t)pdata->VL53LX_p_010, pdata->peak_duration_us);
+
+		pdata->avg_signal_count_rate_mcps = VL53LX_rate_maths((int32_t)pdata->VL53LX_p_010, pdata->woi_duration_us);
+
+		pdata->ambient_count_rate_mcps    = VL53LX_rate_maths((int32_t)pdata->VL53LX_p_016, pdata->woi_duration_us);
+
+		count_rate_total = (uint32_t)pdata->peak_signal_count_rate_mcps + (uint32_t)pdata->ambient_count_rate_mcps;
+
+		if (histo_merge_nb > 1)
+			count_rate_total /= histo_merge_nb;
+
+		pdata->total_rate_per_spad_mcps = VL53LX_rate_per_spad_maths(0x06, count_rate_total, pdata->VL53LX_p_004, 0xFFFF);
+
+		pdata->VL53LX_p_009 = 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  = VL53LX_ERROR_NONE;
+
+	VL53LX_hist_pulse_data_t     *ppulse_data;
+	VL53LX_range_data_t          *prange_data;
+	uint8_t                       p = 0;
+	VL53LX_histogram_bin_data_t *pB = &(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 = pbins_input->cfg_device_state;
+	presults->rd_device_state  = pbins_input->rd_device_state;
+	presults->zone_id          = pbins_input->zone_id;
+	presults->stream_count     = pbins_input->result__stream_count;
+	presults->wrap_dmax_mm     = 0;
+	presults->max_results      = VL53LX_MAX_RANGE_RESULTS;
+	presults->active_results   = 0;
+
+	for (p = 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++)
+		presults->VL53LX_p_022[p] = 0;
+
+	VL53LX_hist_calc_zero_distance_phase(&(palgo3->VL53LX_p_006));
+
+	VL53LX_hist_estimate_ambient_from_thresholded_bins((int32_t)ppost_cfg->ambient_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 = ppost_cfg->ambient_thresh_sigma1;
+
+	for (p = 0; p < VL53LX_MAX_AMBIENT_DMAX_VALUES; p++) {
+		if (status == VL53LX_ERROR_NONE) {
+			status =
+			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 == VL53LX_ERROR_NONE)
+		status =
+			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 == VL53LX_ERROR_NONE)
+		status = VL53LX_f_007(palgo3);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_f_008(palgo3);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_f_009(palgo3);
+
+	for (p = 0; p < palgo3->VL53LX_p_046; p++) {
+		ppulse_data = &(palgo3->VL53LX_p_003[p]);
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_f_010(p, &(palgo3->VL53LX_p_006), palgo3);
+
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_f_011(p, &(palgo3->VL53LX_p_006), palgo3, pB->VL53LX_p_028, &(palgo3->VL53LX_p_048));
+
+		if (status == VL53LX_ERROR_NONE) {
+			status = VL53LX_f_011(p, &(palgo3->VL53LX_p_006), palgo3, 0, &(palgo3->VL53LX_p_049));
+		}
+
+		if (status == VL53LX_ERROR_NONE) {
+			status = VL53LX_f_011(p, &(palgo3->VL53LX_p_047), palgo3, 0, &(palgo3->VL53LX_p_050));
+		}
+
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_f_026(p, &(palgo3->VL53LX_p_048), palgo3, pfiltered);
+
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_f_027(p, ppost_cfg->noise_threshold, pfiltered, palgo3);
+
+		if (status == VL53LX_ERROR_NONE)
+			status =
+			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 == VL53LX_ERROR_NONE)
+			status = VL53LX_f_015(p, 1, &(palgo3->VL53LX_p_006), palgo3);
+	}
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_f_016(ppost_cfg->hist_target_order, palgo3);
+
+	for (p = 0; p < palgo3->VL53LX_p_046; p++) {
+		ppulse_data = &(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 = &(presults->VL53LX_p_003[presults->active_results]);
+			if (status == 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 == VL53LX_ERROR_NONE)
+				status = VL53LX_f_018(pB->vcsel_width, pB->VL53LX_p_015, pB->total_periods_elapsed, pB->result__dss_actual_effective_spads, prange_data, histo_merge_nb);
+
+			if (status == VL53LX_ERROR_NONE)
+				VL53LX_f_019(ppost_cfg->gain_factor, ppost_cfg->range_offset_mm, prange_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  = VL53LX_ERROR_NONE;
+
+	VL53LX_hist_gen3_algo_private_data_t *palgo_gen3 = (VL53LX_hist_gen3_algo_private_data_t *) pArea1;
+	VL53LX_hist_gen4_algo_filtered_data_t *pfiltered4 = (VL53LX_hist_gen4_algo_filtered_data_t *) pArea2;
+	VL53LX_hist_gen3_dmax_private_data_t dmax_algo_gen3;
+	VL53LX_hist_gen3_dmax_private_data_t  *pdmax_algo_gen3 = &dmax_algo_gen3;
+	VL53LX_histogram_bin_data_t             bins_averaged;
+	VL53LX_histogram_bin_data_t           *pbins_averaged = &bins_averaged;
+	VL53LX_range_data_t                   *pdata;
+	uint32_t xtalk_rate_kcps               = 0;
+	uint32_t max_xtalk_rate_per_spad_kcps  = 0;
+	uint8_t  xtalk_enable                  = 0;
+	uint8_t  r                             = 0;
+	uint8_t  t                             = 0;
+	uint32_t XtalkDetectMaxSigma           = 0;
+	int16_t  delta_mm                      = 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 == VL53LX_ERROR_NONE) && (ppost_cfg->algo__crosstalk_compensation_enable > 0))
+		status =
+		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 == VL53LX_ERROR_NONE) && (ppost_cfg->algo__crosstalk_compensation_enable > 0))
+		status = VL53LX_f_033(pbins_averaged, &(pxtalk_shape->xtalk_shape), xtalk_rate_kcps, &(pxtalk_shape->xtalk_hist_removed));
+
+	presults->xmonitor.total_periods_elapsed = pbins_averaged->total_periods_elapsed;
+	presults->xmonitor.VL53LX_p_004 = pbins_averaged->result__dss_actual_effective_spads;
+
+	presults->xmonitor.peak_signal_count_rate_mcps = 0;
+	presults->xmonitor.VL53LX_p_009     = 0;
+
+	presults->xmonitor.range_id     = 0;
+	presults->xmonitor.range_status = VL53LX_DEVICEERROR_NOUPDATE;
+
+	xtalk_enable = 0;
+	if (ppost_cfg->algo__crosstalk_compensation_enable > 0)
+		xtalk_enable = 1;
+
+	for (r = 0 ; r <= xtalk_enable ; r++) {
+		ppost_cfg->algo__crosstalk_compensation_enable = r;
+		status =
+		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 == VL53LX_ERROR_NONE && r == 0))
+			continue;
+
+		if (presults->active_results == 0) {
+			pdata = &(presults->VL53LX_p_003[0]);
+			pdata->ambient_count_rate_mcps = pdmax_algo_gen3->VL53LX_p_034;
+			pdata->VL53LX_p_004 = pdmax_algo_gen3->VL53LX_p_004;
+		}
+
+		max_xtalk_rate_per_spad_kcps = (uint32_t)(ppost_cfg->algo__crosstalk_detect_max_valid_rate_kcps);
+		max_xtalk_rate_per_spad_kcps *= (uint32_t)(*HistMergeNumber);
+		max_xtalk_rate_per_spad_kcps <<= 4;
+
+		for (t = 0 ; t < presults->active_results ; t++) {
+			pdata = &(presults->VL53LX_p_003[t]);
+			if (pdata->max_range_mm > pdata->min_range_mm)
+				delta_mm = pdata->max_range_mm - pdata->min_range_mm;
+			else
+				delta_mm = pdata->min_range_mm - pdata->max_range_mm;
+
+			XtalkDetectMaxSigma = ppost_cfg->algo__crosstalk_detect_max_sigma_mm;
+			XtalkDetectMaxSigma *= (uint32_t)(*HistMergeNumber);
+			XtalkDetectMaxSigma <<= 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 = xtalk_enable;
+	return status;
+}
+
+VL53LX_Error VL53LX_hist_wrap_dmax(VL53LX_hist_post_process_config_t *phistpostprocess, VL53LX_histogram_bin_data_t *pcurrent, int16_t *pwrap_dmax_mm)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	uint32_t  pll_period_mm        = 0;
+	uint32_t  wrap_dmax_phase      = 0;
+	uint32_t  range_mm             = 0;
+
+	*pwrap_dmax_mm = 0;
+
+	if (pcurrent->VL53LX_p_015 != 0) {
+		pll_period_mm = VL53LX_calc_pll_period_mm(pcurrent->VL53LX_p_015);
+
+		wrap_dmax_phase = (uint32_t)phistpostprocess->valid_phase_high << 8;
+
+		range_mm = wrap_dmax_phase * pll_period_mm;
+		range_mm = (range_mm + (1<<14)) >> 15;
+
+		*pwrap_dmax_mm = (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         = VL53LX_ERROR_NONE;
+
+	SUPPRESS_UNUSED_WARNING(Dev);
+
+	status = VL53LX_hist_process_data(pdmax_cal, pdmax_cfg, ppost_cfg, pbins, 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 = VL53LX_ERROR_NONE;
+	int64_t   tmpp                   = 0;
+	int64_t   tmpc                   = 0;
+	int64_t   events_scaler          = 0;
+	int64_t   events_scaler_sq       = 0;
+	int64_t   c_signal_events        = 0;
+	int64_t   c_sig_noise_sq         = 0;
+	int64_t   c_amb_noise_sq         = 0;
+	int64_t   p_amb_noise_sq         = 0;
+	int32_t   p_signal_events        = 0;
+	uint32_t  noise_sq_sum           = 0;
+
+	if (event_sigma == 0) {
+		*prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE;
+		return status;
+	}
+
+	tmpp  = 1 + (int64_t)phist_prev->total_periods_elapsed;
+	tmpp *= (int64_t)phist_prev->result__dss_actual_effective_spads;
+
+	tmpc  = 1 + (int64_t)prange_curr->total_periods_elapsed;
+	tmpc *= (int64_t)prange_curr->VL53LX_p_004;
+
+	events_scaler  = tmpp * 4096;
+	if (tmpc != 0) {
+		events_scaler += (tmpc/2);
+		events_scaler  = do_division_s(events_scaler, tmpc);
+	}
+
+	events_scaler_sq  = events_scaler * events_scaler;
+	events_scaler_sq += 2048;
+	events_scaler_sq /= 4096;
+
+	c_signal_events  = (int64_t)prange_curr->VL53LX_p_017;
+	c_signal_events -= (int64_t)prange_curr->VL53LX_p_016;
+	c_signal_events *= (int64_t)events_scaler;
+	c_signal_events += 2048;
+	c_signal_events /= 4096;
+
+	c_sig_noise_sq  = (int64_t)events_scaler_sq;
+	c_sig_noise_sq *= (int64_t)prange_curr->VL53LX_p_017;
+	c_sig_noise_sq += 2048;
+	c_sig_noise_sq /= 4096;
+
+	c_amb_noise_sq  = (int64_t)events_scaler_sq;
+	c_amb_noise_sq *= (int64_t)prange_curr->VL53LX_p_016;
+	c_amb_noise_sq += 2048;
+	c_amb_noise_sq /= 4096;
+
+	c_amb_noise_sq += 2;
+	c_amb_noise_sq /= 4;
+
+	p_amb_noise_sq  = (int64_t)prange_prev->VL53LX_p_016;
+
+	p_amb_noise_sq += 2;
+	p_amb_noise_sq /= 4;
+
+	noise_sq_sum = (uint32_t)prange_prev->VL53LX_p_017 + (uint32_t)c_sig_noise_sq + (uint32_t)p_amb_noise_sq + (uint32_t)c_amb_noise_sq;
+
+	*pevents_tolerance = (int32_t)VL53LX_isqrt(noise_sq_sum * 16);
+	*pevents_tolerance *= (int32_t)event_sigma;
+	*pevents_tolerance += 32;
+	*pevents_tolerance /= 64;
+
+	p_signal_events  = (int32_t)prange_prev->VL53LX_p_017;
+	p_signal_events -= (int32_t)prange_prev->VL53LX_p_016;
+
+	if ((int32_t)c_signal_events > p_signal_events)
+		*pevents_delta = (int32_t)c_signal_events - p_signal_events;
+	else
+		*pevents_delta = p_signal_events - (int32_t)c_signal_events;
+
+	if (*pevents_delta > *pevents_tolerance && prange_curr->VL53LX_p_004 > min_effective_spad_count)
+		*prange_status = VL53LX_DEVICEERROR_EVENTCONSISTENCY;
+	else
+		*prange_status = 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   = VL53LX_ERROR_NONE;
+	int16_t       delta_mm = 0;
+
+	if (pdata->max_range_mm > pdata->min_range_mm)
+		delta_mm = pdata->max_range_mm - pdata->min_range_mm;
+	else
+		delta_mm = pdata->min_range_mm - pdata->max_range_mm;
+
+	if (min_max_tolerance_mm > 0 && delta_mm > min_max_tolerance_mm)
+		*prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE;
+	else
+		*prange_status = VL53LX_DEVICEERROR_RANGECOMPLETE;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_hist_phase_consistency_check(VL53LX_DEV Dev, VL53LX_zone_hist_info_t *phist_prev, VL53LX_zone_objects_t *prange_prev, VL53LX_range_results_t *prange_curr)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	uint8_t   lc = 0;
+	uint8_t   p = 0;
+	uint16_t  phase_delta      = 0;
+	uint16_t  phase_tolerance  = 0;
+	int32_t   events_delta     = 0;
+	int32_t   events_tolerance = 0;
+	uint8_t event_sigma;
+	uint16_t event_min_spad_count;
+	uint16_t min_max_tolerance;
+	uint8_t pht;
+
+	VL53LX_DeviceError  range_status = 0;
+
+	event_sigma = pdev->histpostprocess.algo__consistency_check__event_sigma;
+	event_min_spad_count = pdev->histpostprocess.algo__consistency_check__event_min_spad_count;
+	min_max_tolerance = pdev->histpostprocess.algo__consistency_check__min_max_tolerance;
+	pht = pdev->histpostprocess.algo__consistency_check__phase_tolerance;
+	phase_tolerance = (uint16_t)pht;
+	phase_tolerance = phase_tolerance << 8;
+
+	if (prange_prev->rd_device_state != VL53LX_DEVICESTATE_RANGING_GATHER_DATA &&
+		prange_prev->rd_device_state != VL53LX_DEVICESTATE_RANGING_OUTPUT_DATA)
+		return status;
+
+	if (phase_tolerance == 0)
+		return status;
+
+	for (lc = 0; lc < prange_curr->active_results; lc++) {
+		if (!((prange_curr->VL53LX_p_003[lc].range_status ==
+			VL53LX_DEVICEERROR_RANGECOMPLETE) ||
+			(prange_curr->VL53LX_p_003[lc].range_status ==
+			VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK)))
+			continue;
+
+		if (prange_prev->active_objects == 0)
+			prange_curr->VL53LX_p_003[lc].range_status = VL53LX_DEVICEERROR_PREV_RANGE_NO_TARGETS;
+		else
+			prange_curr->VL53LX_p_003[lc].range_status = VL53LX_DEVICEERROR_PHASECONSISTENCY;
+
+		for (p = 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 = prange_curr->VL53LX_p_003[lc].VL53LX_p_011 - prange_prev->VL53LX_p_003[p].VL53LX_p_011;
+			} else {
+				phase_delta = prange_prev->VL53LX_p_003[p].VL53LX_p_011 - prange_curr->VL53LX_p_003[lc].VL53LX_p_011;
+			}
+
+			if (phase_delta < phase_tolerance) {
+				if (status == VL53LX_ERROR_NONE)
+					status =
+					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 == VL53LX_ERROR_NONE && range_status == VL53LX_DEVICEERROR_RANGECOMPLETE)
+					status = VL53LX_hist_merged_pulse_check(min_max_tolerance, &(prange_curr->VL53LX_p_003[lc]), &range_status);
+
+				prange_curr->VL53LX_p_003[lc].range_status = 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_range_data_t *prange_curr)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	int32_t   events_delta     = 0;
+	int32_t   events_tolerance = 0;
+	uint8_t event_sigma;
+	uint16_t min_spad_count;
+
+	event_sigma = pdev->histpostprocess.algo__crosstalk_detect_event_sigma;
+	min_spad_count = pdev->histpostprocess.algo__consistency_check__event_min_spad_count;
+
+	if (prange_curr->range_status == VL53LX_DEVICEERROR_RANGECOMPLETE ||
+		prange_curr->range_status == VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK ||
+		prange_curr->range_status == VL53LX_DEVICEERROR_EVENTCONSISTENCY) {
+
+		if (prange_prev->xmonitor.range_status == VL53LX_DEVICEERROR_RANGECOMPLETE ||
+			prange_prev->xmonitor.range_status == VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK ||
+			prange_prev->xmonitor.range_status == VL53LX_DEVICEERROR_EVENTCONSISTENCY) {
+			prange_curr->range_status = VL53LX_DEVICEERROR_RANGECOMPLETE;
+
+			status =
+				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                       = 0xFF;
+	pdata->result__range_status                           = 0xFF;
+	pdata->result__report_status                          = 0xFF;
+	pdata->result__stream_count                           = 0xFF;
+	pdata->result__dss_actual_effective_spads_sd0         = 0xFFFF;
+	pdata->result__peak_signal_count_rate_mcps_sd0        = 0xFFFF;
+	pdata->result__ambient_count_rate_mcps_sd0            = 0xFFFF;
+	pdata->result__sigma_sd0                              = 0xFFFF;
+	pdata->result__phase_sd0                              = 0xFFFF;
+	pdata->result__final_crosstalk_corrected_range_mm_sd0 = 0xFFFF;
+	pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 = 0xFFFF;
+	pdata->result__mm_inner_actual_effective_spads_sd0    = 0xFFFF;
+	pdata->result__mm_outer_actual_effective_spads_sd0    = 0xFFFF;
+	pdata->result__avg_signal_count_rate_mcps_sd0         = 0xFFFF;
+	pdata->result__dss_actual_effective_spads_sd1         = 0xFFFF;
+	pdata->result__peak_signal_count_rate_mcps_sd1        = 0xFFFF;
+	pdata->result__ambient_count_rate_mcps_sd1            = 0xFFFF;
+	pdata->result__sigma_sd1                              = 0xFFFF;
+	pdata->result__phase_sd1                              = 0xFFFF;
+	pdata->result__final_crosstalk_corrected_range_mm_sd1 = 0xFFFF;
+	pdata->result__spare_0_sd1                            = 0xFFFF;
+	pdata->result__spare_1_sd1                            = 0xFFFF;
+	pdata->result__spare_2_sd1                            = 0xFFFF;
+	pdata->result__spare_3_sd1                            = 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 = 0;
+	VL53LX_range_data_t  *pdata;
+
+	VL53LX_init_system_results(psys);
+
+	psys->result__interrupt_status = pbins->result__interrupt_status;
+	psys->result__range_status     = phist->active_results;
+	psys->result__report_status    = pbins->result__report_status;
+	psys->result__stream_count     = pbins->result__stream_count;
+
+	pdata = &(phist->VL53LX_p_003[0]);
+
+	for (i = 0; i < phist->active_results; i++) {
+		switch (i) {
+		case 0:
+			psys->result__dss_actual_effective_spads_sd0 = pdata->VL53LX_p_004;
+			psys->result__peak_signal_count_rate_mcps_sd0 = pdata->peak_signal_count_rate_mcps;
+			psys->result__avg_signal_count_rate_mcps_sd0 = pdata->avg_signal_count_rate_mcps;
+			psys->result__ambient_count_rate_mcps_sd0 = pdata->ambient_count_rate_mcps;
+			psys->result__sigma_sd0 = pdata->VL53LX_p_002;
+			psys->result__phase_sd0 = pdata->VL53LX_p_011;
+			psys->result__final_crosstalk_corrected_range_mm_sd0 = (uint16_t)pdata->median_range_mm;
+			psys->result__phase_sd1  = pdata->zero_distance_phase;
+			pcore->result_core__ranging_total_events_sd0 = pdata->VL53LX_p_017;
+			pcore->result_core__signal_total_events_sd0 = pdata->VL53LX_p_010;
+			pcore->result_core__total_periods_elapsed_sd0 = pdata->total_periods_elapsed;
+			pcore->result_core__ambient_window_events_sd0 = pdata->VL53LX_p_016;
+			break;
+		case 1:
+			psys->result__dss_actual_effective_spads_sd1 = pdata->VL53LX_p_004;
+			psys->result__peak_signal_count_rate_mcps_sd1 = pdata->peak_signal_count_rate_mcps;
+			psys->result__ambient_count_rate_mcps_sd1 = pdata->ambient_count_rate_mcps;
+			psys->result__sigma_sd1 = pdata->VL53LX_p_002;
+			psys->result__phase_sd1 = pdata->VL53LX_p_011;
+			psys->result__final_crosstalk_corrected_range_mm_sd1 = (uint16_t)pdata->median_range_mm;
+			pcore->result_core__ranging_total_events_sd1 = pdata->VL53LX_p_017;
+			pcore->result_core__signal_total_events_sd1 = pdata->VL53LX_p_010;
+			pcore->result_core__total_periods_elapsed_sd1 = pdata->total_periods_elapsed;
+			pcore->result_core__ambient_window_events_sd1 = pdata->VL53LX_p_016;
+			break;
+		}
+		pdata++;
+	}
+}
+
+VL53LX_Error VL53LX_dynamic_zone_update(VL53LX_DEV Dev, VL53LX_range_results_t *presults)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t  *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t  *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+	VL53LX_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs);
+
+	uint8_t   zone_id = pdev->ll_state.rd_zone_id;
+	uint8_t   i;
+	uint16_t  max_total_rate_per_spads;
+	uint16_t  target_rate = pdev->stat_cfg.dss_config__target_total_rate_mcps;
+	uint32_t  temp = 0xFFFF;
+#ifdef VL53LX_LOG_ENABLE
+	uint16_t eff_spad_cnt =
+		pZ->VL53LX_p_003[zone_id].dss_requested_effective_spad_count;
+#endif
+
+	pZ->VL53LX_p_003[zone_id].dss_requested_effective_spad_count = 0;
+
+	max_total_rate_per_spads = presults->VL53LX_p_003[0].total_rate_per_spad_mcps;
+
+	for (i = 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 = presults->VL53LX_p_003[i].total_rate_per_spad_mcps;
+	}
+
+	if (max_total_rate_per_spads == 0) {
+		temp = 0xFFFF;
+	} else {
+		temp = target_rate << 14;
+		temp = temp / max_total_rate_per_spads;
+		if (temp > 0xFFFF)
+			temp = 0xFFFF;
+	}
+
+	pZ->VL53LX_p_003[zone_id].dss_requested_effective_spad_count = (uint16_t)temp;
+
+	return status;
+}
+
+void VL53LX_copy_hist_bins_to_static_cfg(VL53LX_histogram_config_t *phistogram, VL53LX_static_config_t *pstatic, VL53LX_timing_config_t *ptiming)
+{
+	pstatic->sigma_estimator__effective_pulse_width_ns = phistogram->histogram_config__high_amb_even_bin_0_1;
+	pstatic->sigma_estimator__effective_ambient_width_ns = phistogram->histogram_config__high_amb_even_bin_2_3;
+	pstatic->sigma_estimator__sigma_ref_mm = phistogram->histogram_config__high_amb_even_bin_4_5;
+	pstatic->algo__crosstalk_compensation_valid_height_mm = phistogram->histogram_config__high_amb_odd_bin_0_1;
+	pstatic->spare_host_config__static_config_spare_0 = phistogram->histogram_config__high_amb_odd_bin_2_3;
+	pstatic->spare_host_config__static_config_spare_1 = phistogram->histogram_config__high_amb_odd_bin_4_5;
+	pstatic->algo__range_ignore_threshold_mcps =
+		(((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 = phistogram->histogram_config__mid_amb_even_bin_4_5;
+	pstatic->algo__range_min_clip = phistogram->histogram_config__mid_amb_odd_bin_0_1;
+	pstatic->algo__consistency_check__tolerance = phistogram->histogram_config__mid_amb_odd_bin_2;
+	pstatic->spare_host_config__static_config_spare_2 = phistogram->histogram_config__mid_amb_odd_bin_3_4;
+	pstatic->sd_config__reset_stages_msb = phistogram->histogram_config__mid_amb_odd_bin_5;
+	ptiming->range_config__sigma_thresh =
+		(((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 =
+		(((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 =
+			phistogram->histogram_config__low_amb_odd_bin_2_3;
+	ptiming->range_config__valid_phase_high =
+			phistogram->histogram_config__low_amb_odd_bin_4_5;
+}
+
+VL53LX_Error VL53LX_multizone_hist_bins_update(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_histogram_config_t *phist_cfg = &(pdev->hist_cfg);
+
+	if (status == 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 = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+	VL53LX_smudge_corrector_config_t *pconfig = &(pdev->smudge_correct_config);
+	VL53LX_smudge_corrector_internals_t *pint = &(pdev->smudge_corrector_internals);
+	VL53LX_range_results_t *presults = &(pres->range_results);
+	VL53LX_range_data_t *pxmonitor = &(presults->xmonitor);
+
+	uint32_t peak_duration_us = pxmonitor->peak_duration_us;
+	uint64_t temp64a;
+	uint64_t temp64z;
+
+	temp64a = pxmonitor->VL53LX_p_017 + pxmonitor->VL53LX_p_016;
+	if (peak_duration_us == 0)
+		peak_duration_us = 1000;
+	temp64a = do_division_u((temp64a * 1000), peak_duration_us);
+	temp64a = do_division_u((temp64a * 1000), peak_duration_us);
+
+	temp64z = pconfig->noise_margin * pxmonitor->VL53LX_p_004;
+	if (temp64z == 0)
+		temp64z = 1;
+	temp64a = temp64a * 1000 * 256;
+	temp64a = do_division_u(temp64a, temp64z);
+	temp64a = temp64a * 1000 * 256;
+	temp64a = do_division_u(temp64a, temp64z);
+
+	pint->required_samples = (uint32_t)temp64a;
+
+	if (pint->required_samples < 2)
+		pint->required_samples = 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 = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = 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 = &(pdev->xtalk_cfg);
+	VL53LX_xtalk_calibration_results_t  *pC = &(pdev->xtalk_cal);
+	uint32_t *pcpo;
+	uint32_t max, nXtalk, cXtalk;
+	uint32_t incXtalk, cval;
+
+	if (add_smudge == 1) {
+		pout->algo__crosstalk_compensation_plane_offset_kcps = (uint32_t)xtalk_offset_out + (uint32_t)pconfig->smudge_margin;
+	} else {
+		pout->algo__crosstalk_compensation_plane_offset_kcps = (uint32_t)xtalk_offset_out;
+	}
+
+	orig_xtalk_offset = pX->nvm_default__crosstalk_compensation_plane_offset_kcps;
+	orig_x_gradient = pX->nvm_default__crosstalk_compensation_x_plane_gradient_kcps;
+	orig_y_gradient = pX->nvm_default__crosstalk_compensation_y_plane_gradient_kcps;
+
+	if (((pconfig->user_scaler_set == 0) || (pconfig->scaler_calc_method == 1)) && (pC->algo__crosstalk_compensation_plane_offset_kcps != 0)) {
+		VL53LX_compute_histo_merge_nb(Dev, &histo_merge_nb);
+
+		if (histo_merge_nb == 0)
+			histo_merge_nb = 1;
+		if (pdev->tuning_parms.tp_hist_merge != 1)
+			orig_xtalk_offset = pC->algo__crosstalk_compensation_plane_offset_kcps;
+		else
+			orig_xtalk_offset = pC->algo__xtalk_cpo_HistoMerge_kcps[histo_merge_nb-1];
+
+		orig_x_gradient = pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
+		orig_y_gradient = pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
+	}
+
+	if ((pconfig->user_scaler_set == 0) && (orig_x_gradient == 0))
+		pout->gradient_zero_flag |= 0x01;
+
+	if ((pconfig->user_scaler_set == 0) && (orig_y_gradient == 0))
+		pout->gradient_zero_flag |= 0x02;
+
+	if (orig_xtalk_offset == 0)
+		orig_xtalk_offset = 1;
+
+	if (pconfig->user_scaler_set == 1) {
+		x_gradient_scaler = pconfig->x_gradient_scaler;
+		y_gradient_scaler = pconfig->y_gradient_scaler;
+	} else {
+		x_gradient_scaler = (int16_t)do_division_s((((int32_t)orig_x_gradient) << 6), orig_xtalk_offset);
+		pconfig->x_gradient_scaler = x_gradient_scaler;
+		y_gradient_scaler = (int16_t)do_division_s((((int32_t)orig_y_gradient) << 6), orig_xtalk_offset);
+		pconfig->y_gradient_scaler = y_gradient_scaler;
+	}
+
+	if (pconfig->scaler_calc_method == 0) {
+		itemp32 = (int32_t)(pout->algo__crosstalk_compensation_plane_offset_kcps * x_gradient_scaler);
+		itemp32 = itemp32 >> 6;
+		if (itemp32 > 0xFFFF)
+			itemp32 = 0xFFFF;
+
+		pout->algo__crosstalk_compensation_x_plane_gradient_kcps = (int16_t)itemp32;
+
+		itemp32 = (int32_t)(pout->algo__crosstalk_compensation_plane_offset_kcps * y_gradient_scaler);
+		itemp32 = itemp32 >> 6;
+		if (itemp32 > 0xFFFF)
+			itemp32 = 0xFFFF;
+
+		pout->algo__crosstalk_compensation_y_plane_gradient_kcps = (int16_t)itemp32;
+	} else if (pconfig->scaler_calc_method == 1) {
+		itemp32 = (int32_t)(orig_xtalk_offset - pout->algo__crosstalk_compensation_plane_offset_kcps);
+		itemp32 = (int32_t)(do_division_s(itemp32, 16));
+		itemp32 = itemp32 << 2;
+		itemp32 = itemp32 + (int32_t)(orig_x_gradient);
+		if (itemp32 > 0xFFFF)
+			itemp32 = 0xFFFF;
+
+		pout->algo__crosstalk_compensation_x_plane_gradient_kcps = (int16_t)itemp32;
+
+		itemp32 = (int32_t)(orig_xtalk_offset - pout->algo__crosstalk_compensation_plane_offset_kcps);
+		itemp32 = (int32_t)(do_division_s(itemp32, 80));
+		itemp32 = itemp32 << 2;
+		itemp32 = itemp32 + (int32_t)(orig_y_gradient);
+		if (itemp32 > 0xFFFF)
+			itemp32 = 0xFFFF;
+
+		pout->algo__crosstalk_compensation_y_plane_gradient_kcps = (int16_t)itemp32;
+	}
+
+	if ((pconfig->smudge_corr_apply_enabled == 1) && (soft_update != 1)) {
+		pout->new_xtalk_applied_flag = 1;
+		nXtalk = pout->algo__crosstalk_compensation_plane_offset_kcps;
+		VL53LX_compute_histo_merge_nb(Dev, &histo_merge_nb);
+		max = pdev->tuning_parms.tp_hist_merge_max_size;
+		pcpo = &(pC->algo__xtalk_cpo_HistoMerge_kcps[0]);
+		if ((histo_merge_nb > 0) && (pdev->tuning_parms.tp_hist_merge == 1) && (nXtalk != 0)) {
+			cXtalk = pX->algo__crosstalk_compensation_plane_offset_kcps;
+			SmudgeFactor = cXtalk * 1000 / nXtalk;
+			if ((max ==  0) || (SmudgeFactor >= pconfig->max_smudge_factor))
+				pout->new_xtalk_applied_flag = 0;
+			else {
+				incXtalk = nXtalk / max;
+				cval = 0;
+				for (i = 0; i < max-1; i++) {
+					cval += incXtalk;
+					*pcpo = cval;
+					pcpo++;
+				}
+				*pcpo = nXtalk;
+			}
+		}
+		if (pout->new_xtalk_applied_flag) {
+			pX->algo__crosstalk_compensation_plane_offset_kcps =
+			pout->algo__crosstalk_compensation_plane_offset_kcps;
+			pX->algo__crosstalk_compensation_x_plane_gradient_kcps =
+			pout->algo__crosstalk_compensation_x_plane_gradient_kcps;
+			pX->algo__crosstalk_compensation_y_plane_gradient_kcps =
+			pout->algo__crosstalk_compensation_y_plane_gradient_kcps;
+
+			if (pconfig->smudge_corr_single_apply == 1) {
+				pconfig->smudge_corr_apply_enabled = 0;
+				pconfig->smudge_corr_single_apply = 0;
+			}
+		}
+	}
+
+	if (soft_update != 1)
+		pout->smudge_corr_valid = 1;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_dynamic_xtalk_correction_corrector(VL53LX_DEV Dev)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+	VL53LX_smudge_corrector_config_t *pconfig = &(pdev->smudge_correct_config);
+	VL53LX_smudge_corrector_internals_t *pint = &(pdev->smudge_corrector_internals);
+	VL53LX_smudge_corrector_data_t *pout = &(pres->range_results.smudge_corrector_data);
+	VL53LX_range_results_t  *pR = &(pres->range_results);
+	VL53LX_xtalk_config_t  *pX = &(pdev->xtalk_cfg);
+
+	uint8_t	run_smudge_detection = 0;
+	uint8_t merging_complete = 0;
+	uint8_t	run_nodetect = 0;
+	uint8_t ambient_check = 0;
+	int32_t itemp32 = 0;
+	uint64_t utemp64 = 0;
+	uint8_t continue_processing = CONT_CONTINUE;
+	uint32_t xtalk_offset_out = 0;
+	uint32_t xtalk_offset_in = 0;
+	uint32_t current_xtalk = 0;
+	uint32_t smudge_margin_adjusted = 0;
+	uint8_t i = 0;
+	uint8_t nodetect_index = 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 == 0) || (pdev->tuning_parms.tp_hist_merge != 1))
+		histo_merge_nb = 1;
+
+	VL53LX_dynamic_xtalk_correction_output_init(pres);
+
+	ambient_check = (pconfig->smudge_corr_ambient_threshold == 0) ||
+		((pconfig->smudge_corr_ambient_threshold * histo_merge_nb)  >
+		((uint32_t)pR->xmonitor.ambient_count_rate_mcps));
+
+	merging_complete = ((pdev->tuning_parms.tp_hist_merge != 1) || (histo_merge_nb == pdev->tuning_parms.tp_hist_merge_max_size));
+	run_smudge_detection = (pconfig->smudge_corr_enabled == 1) && ambient_check && (pR->xmonitor.range_status == VL53LX_DEVICEERROR_RANGECOMPLETE) && merging_complete;
+
+	if ((pR->xmonitor.range_status != VL53LX_DEVICEERROR_RANGECOMPLETE) && (pconfig->smudge_corr_enabled == 1)) {
+		run_nodetect = 2;
+		for (i = 0; i < pR->active_results; i++) {
+			if (pR->VL53LX_p_003[i].range_status == VL53LX_DEVICEERROR_RANGECOMPLETE) {
+				if (pR->VL53LX_p_003[i].median_range_mm <= pconfig->nodetect_min_range_mm) {
+					run_nodetect = 0;
+				} else {
+					if (run_nodetect == 2) {
+						run_nodetect = 1;
+						nodetect_index = i;
+					}
+				}
+			}
+		}
+
+		if (run_nodetect == 2)
+			run_nodetect = 0;
+
+		amr = pR->VL53LX_p_003[nodetect_index].ambient_count_rate_mcps;
+
+		if (run_nodetect == 1) {
+			utemp64 = 1000 * ((uint64_t)amr);
+			utemp64 = utemp64 << 9;
+
+			if (utemp64 < pconfig->nodetect_ambient_threshold)
+				run_nodetect = 1;
+			else
+				run_nodetect = 0;
+		}
+	}
+
+	if (run_smudge_detection) {
+		pint->nodetect_counter = 0;
+		VL53LX_dynamic_xtalk_correction_calc_required_samples(Dev);
+
+		xtalk_offset_in = pR->xmonitor.VL53LX_p_009;
+
+		cco = pX->algo__crosstalk_compensation_plane_offset_kcps;
+		current_xtalk = ((uint32_t)cco) << 2;
+
+		smudge_margin_adjusted = ((uint32_t)(pconfig->smudge_margin)) << 2;
+
+		itemp32 = xtalk_offset_in - current_xtalk + smudge_margin_adjusted;
+
+		if (itemp32 < 0)
+			itemp32 = itemp32 * (-1);
+
+		if (itemp32 > ((int32_t)pconfig->single_xtalk_delta)) {
+			if ((int32_t)xtalk_offset_in > ((int32_t)current_xtalk - (int32_t)smudge_margin_adjusted)) {
+				pout->single_xtalk_delta_flag = 1;
+			} else {
+				pout->single_xtalk_delta_flag = 2;
+			}
+		}
+
+		pint->current_samples = pint->current_samples + 1;
+
+		if (pint->current_samples > pconfig->sample_limit) {
+			pout->sample_limit_exceeded_flag = 1;
+			continue_processing = CONT_RESET;
+		} else {
+			pint->accumulator = pint->accumulator + xtalk_offset_in;
+		}
+
+		if (pint->current_samples < pint->required_samples)
+			continue_processing = CONT_NEXT_LOOP;
+
+		xtalk_offset_out = (uint32_t)(do_division_u(pint->accumulator, pint->current_samples));
+
+		itemp32 = xtalk_offset_out - current_xtalk + smudge_margin_adjusted;
+
+		if (itemp32 < 0)
+			itemp32 = itemp32 * (-1);
+
+		if (continue_processing == CONT_CONTINUE && (itemp32 >= ((int32_t)(pconfig->averaged_xtalk_delta)))) {
+			if ((int32_t)xtalk_offset_out > ((int32_t)current_xtalk - (int32_t)smudge_margin_adjusted))
+				pout->averaged_xtalk_delta_flag = 1;
+			else
+				pout->averaged_xtalk_delta_flag = 2;
+		}
+
+		if (continue_processing == CONT_CONTINUE && (itemp32 < ((int32_t)(pconfig->averaged_xtalk_delta))))
+			continue_processing = CONT_RESET;
+
+		pout->smudge_corr_clipped = 0;
+		if ((continue_processing == CONT_CONTINUE) && (pconfig->smudge_corr_clip_limit != 0)) {
+			if (xtalk_offset_out > (pconfig->smudge_corr_clip_limit * histo_merge_nb)) {
+				pout->smudge_corr_clipped = 1;
+				continue_processing = CONT_RESET;
+			}
+		}
+
+		if (pconfig->user_xtalk_offset_limit_hi && (xtalk_offset_out > pconfig->user_xtalk_offset_limit))
+			xtalk_offset_out = pconfig->user_xtalk_offset_limit;
+
+		if ((pconfig->user_xtalk_offset_limit_hi == 0) && (xtalk_offset_out < pconfig->user_xtalk_offset_limit))
+			xtalk_offset_out = pconfig->user_xtalk_offset_limit;
+
+		xtalk_offset_out = xtalk_offset_out >> 2;
+		if (xtalk_offset_out > 0x3FFFF)
+			xtalk_offset_out = 0x3FFFF;
+
+		if (continue_processing == CONT_CONTINUE) {
+			VL53LX_dynamic_xtalk_correction_calc_new_xtalk(Dev, xtalk_offset_out, pconfig, pout, 1, 0);
+			continue_processing = CONT_RESET;
+		} else {
+			VL53LX_dynamic_xtalk_correction_calc_new_xtalk(Dev, xtalk_offset_out, pconfig, pout, 1, 1);
+		}
+
+		if (continue_processing == CONT_RESET) {
+			pint->accumulator = 0;
+			pint->current_samples = 0;
+			pint->nodetect_counter = 0;
+		}
+	}
+
+	continue_processing = CONT_CONTINUE;
+	if (run_nodetect == 1) {
+		pint->nodetect_counter += 1;
+		if (pint->nodetect_counter < pconfig->nodetect_sample_limit)
+			continue_processing = CONT_NEXT_LOOP;
+
+		xtalk_offset_out = (uint32_t)(pconfig->nodetect_xtalk_offset);
+
+		if (continue_processing == CONT_CONTINUE) {
+			VL53LX_dynamic_xtalk_correction_calc_new_xtalk(Dev, xtalk_offset_out, pconfig, pout, 0, 0);
+			pout->smudge_corr_valid = 2;
+			continue_processing = CONT_RESET;
+		} else {
+			VL53LX_dynamic_xtalk_correction_calc_new_xtalk(Dev, xtalk_offset_out, pconfig, pout, 0, 1);
+		}
+
+		if (continue_processing == CONT_RESET) {
+			pint->accumulator = 0;
+			pint->current_samples = 0;
+			pint->nodetect_counter = 0;
+		}
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_i2c_decode_debug_results(uint16_t buf_size, uint8_t *pbuffer, VL53LX_debug_results_t *pdata)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+
+	if (buf_size < VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES)
+		return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
+
+	pdata->phasecal_result__reference_phase = (VL53LX_i2c_decode_uint16_t(2, pbuffer +   0));
+	pdata->phasecal_result__vcsel_start = (*(pbuffer +   2)) & 0x7F;
+	pdata->ref_spad_char_result__num_actual_ref_spads = (*(pbuffer +   3)) & 0x3F;
+	pdata->ref_spad_char_result__ref_location = (*(pbuffer +   4)) & 0x3;
+	pdata->vhv_result__coldboot_status = (*(pbuffer +   5)) & 0x1;
+	pdata->vhv_result__search_result = (*(pbuffer +   6)) & 0x3F;
+	pdata->vhv_result__latest_setting = (*(pbuffer +   7)) & 0x3F;
+	pdata->result__osc_calibrate_val = (VL53LX_i2c_decode_uint16_t(2, pbuffer +   8)) & 0x3FF;
+	pdata->ana_config__powerdown_go1 = (*(pbuffer +  10)) & 0x3;
+	pdata->ana_config__ref_bg_ctrl = (*(pbuffer +  11)) & 0x3;
+	pdata->ana_config__regdvdd1v2_ctrl = (*(pbuffer +  12)) & 0xF;
+	pdata->ana_config__osc_slow_ctrl = (*(pbuffer +  13)) & 0x7;
+	pdata->test_mode__status = (*(pbuffer +  14)) & 0x1;
+	pdata->firmware__system_status = (*(pbuffer +  15)) & 0x3;
+	pdata->firmware__mode_status = (*(pbuffer +  16));
+	pdata->firmware__secondary_mode_status = (*(pbuffer +  17));
+	pdata->firmware__cal_repeat_rate_counter = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  18)) & 0xFFF;
+	pdata->gph__system__thresh_high = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  22));
+	pdata->gph__system__thresh_low = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  24));
+	pdata->gph__system__enable_xtalk_per_quadrant = (*(pbuffer +  26)) & 0x1;
+	pdata->gph__spare_0 = (*(pbuffer +  27)) & 0x7;
+	pdata->gph__sd_config__woi_sd0 = (*(pbuffer +  28));
+	pdata->gph__sd_config__woi_sd1 = (*(pbuffer +  29));
+	pdata->gph__sd_config__initial_phase_sd0 = (*(pbuffer +  30)) & 0x7F;
+	pdata->gph__sd_config__initial_phase_sd1 = (*(pbuffer +  31)) & 0x7F;
+	pdata->gph__sd_config__first_order_select = (*(pbuffer +  32)) & 0x3;
+	pdata->gph__sd_config__quantifier = (*(pbuffer +  33)) & 0xF;
+	pdata->gph__roi_config__user_roi_centre_spad = (*(pbuffer +  34));
+	pdata->gph__roi_config__user_roi_requested_global_xy_size = (*(pbuffer +  35));
+	pdata->gph__system__sequence_config = (*(pbuffer +  36));
+	pdata->gph__gph_id = (*(pbuffer +  37)) & 0x1;
+	pdata->system__interrupt_set = (*(pbuffer +  38)) & 0x3;
+	pdata->interrupt_manager__enables = (*(pbuffer +  39)) & 0x1F;
+	pdata->interrupt_manager__clear = (*(pbuffer +  40)) & 0x1F;
+	pdata->interrupt_manager__status = (*(pbuffer +  41)) & 0x1F;
+	pdata->mcu_to_host_bank__wr_access_en = (*(pbuffer +  42)) & 0x1;
+	pdata->power_management__go1_reset_status = (*(pbuffer +  43)) & 0x1;
+	pdata->pad_startup_mode__value_ro = (*(pbuffer +  44)) & 0x3;
+	pdata->pad_startup_mode__value_ctrl = (*(pbuffer +  45)) & 0x3F;
+	pdata->pll_period_us = (VL53LX_i2c_decode_uint32_t(4, pbuffer +  46)) & 0x3FFFF;
+	pdata->interrupt_scheduler__data_out = (VL53LX_i2c_decode_uint32_t(4, pbuffer +  50));
+	pdata->nvm_bist__complete = (*(pbuffer +  54)) & 0x1;
+	pdata->nvm_bist__status = (*(pbuffer +  55)) & 0x1;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_i2c_decode_core_results(uint16_t buf_size, uint8_t *pbuffer, VL53LX_core_results_t *pdata)
+{
+	VL53LX_Error status = 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 = (VL53LX_i2c_decode_uint32_t(4, pbuffer +   0));
+	pdata->result_core__ranging_total_events_sd0 = (VL53LX_i2c_decode_uint32_t(4, pbuffer +   4));
+	pdata->result_core__signal_total_events_sd0 = (VL53LX_i2c_decode_int32_t(4, pbuffer +   8));
+	pdata->result_core__total_periods_elapsed_sd0 = (VL53LX_i2c_decode_uint32_t(4, pbuffer +  12));
+	pdata->result_core__ambient_window_events_sd1 = (VL53LX_i2c_decode_uint32_t(4, pbuffer +  16));
+	pdata->result_core__ranging_total_events_sd1 = (VL53LX_i2c_decode_uint32_t(4, pbuffer +  20));
+	pdata->result_core__signal_total_events_sd1 = (VL53LX_i2c_decode_int32_t(4, pbuffer +  24));
+	pdata->result_core__total_periods_elapsed_sd1 = (VL53LX_i2c_decode_uint32_t(4, pbuffer +  28));
+	pdata->result_core__spare_0 = (*(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 = VL53LX_ERROR_NONE;
+
+	if (buf_size < VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES)
+		return VL53LX_ERROR_COMMS_BUFFER_TOO_SMALL;
+
+	pdata->result__interrupt_status = (*(pbuffer +   0)) & 0x3F;
+	pdata->result__range_status = (*(pbuffer +   1));
+	pdata->result__report_status = (*(pbuffer +   2)) & 0xF;
+	pdata->result__stream_count = (*(pbuffer +   3));
+	pdata->result__dss_actual_effective_spads_sd0 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +   4));
+	pdata->result__peak_signal_count_rate_mcps_sd0 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +   6));
+	pdata->result__ambient_count_rate_mcps_sd0 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +   8));
+	pdata->result__sigma_sd0 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  10));
+	pdata->result__phase_sd0 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  12));
+	pdata->result__final_crosstalk_corrected_range_mm_sd0 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  14));
+	pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  16));
+	pdata->result__mm_inner_actual_effective_spads_sd0 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  18));
+	pdata->result__mm_outer_actual_effective_spads_sd0 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  20));
+	pdata->result__avg_signal_count_rate_mcps_sd0 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  22));
+	pdata->result__dss_actual_effective_spads_sd1 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  24));
+	pdata->result__peak_signal_count_rate_mcps_sd1 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  26));
+	pdata->result__ambient_count_rate_mcps_sd1 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  28));
+	pdata->result__sigma_sd1 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  30));
+	pdata->result__phase_sd1 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  32));
+	pdata->result__final_crosstalk_corrected_range_mm_sd1 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  34));
+	pdata->result__spare_0_sd1 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  36));
+	pdata->result__spare_1_sd1 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  38));
+	pdata->result__spare_2_sd1 = (VL53LX_i2c_decode_uint16_t(2, pbuffer +  40));
+	pdata->result__spare_3_sd1 = (*(pbuffer +  42));
+	pdata->result__thresh_info = (*(pbuffer +  43));
+
+	return status;
+}
+
+VL53LX_Error VL53LX_get_measurement_results(VL53LX_DEV Dev, VL53LX_DeviceResultsLevel device_results_level)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	uint8_t buffer[VL53LX_MAX_I2C_XFER_SIZE];
+	VL53LX_system_results_t   *psystem_results = &(pdev->sys_results);
+	VL53LX_core_results_t     *pcore_results   = &(pdev->core_results);
+	VL53LX_debug_results_t    *pdebug_results  = &(pdev->dbg_results);
+	uint16_t i2c_index               = VL53LX_SYSTEM_RESULTS_I2C_INDEX;
+	uint16_t i2c_buffer_offset_bytes = 0;
+	uint16_t i2c_buffer_size_bytes   = 0;
+
+	switch (device_results_level) {
+	case VL53LX_DEVICERESULTSLEVEL_FULL:
+		i2c_buffer_size_bytes = (VL53LX_DEBUG_RESULTS_I2C_INDEX + VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES) - i2c_index;
+		break;
+	case VL53LX_DEVICERESULTSLEVEL_UPTO_CORE:
+		i2c_buffer_size_bytes = (VL53LX_CORE_RESULTS_I2C_INDEX + VL53LX_CORE_RESULTS_I2C_SIZE_BYTES) - i2c_index;
+		break;
+	default:
+		i2c_buffer_size_bytes = VL53LX_SYSTEM_RESULTS_I2C_SIZE_BYTES;
+		break;
+	}
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_ReadMulti(Dev, i2c_index, buffer, (uint32_t)i2c_buffer_size_bytes);
+
+	if (device_results_level >= VL53LX_DEVICERESULTSLEVEL_FULL && status == VL53LX_ERROR_NONE) {
+		i2c_buffer_offset_bytes = VL53LX_DEBUG_RESULTS_I2C_INDEX - i2c_index;
+		status = VL53LX_i2c_decode_debug_results(VL53LX_DEBUG_RESULTS_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes], pdebug_results);
+	}
+
+	if (device_results_level >= VL53LX_DEVICERESULTSLEVEL_UPTO_CORE && status == VL53LX_ERROR_NONE) {
+		i2c_buffer_offset_bytes = VL53LX_CORE_RESULTS_I2C_INDEX - i2c_index;
+		status = VL53LX_i2c_decode_core_results(VL53LX_CORE_RESULTS_I2C_SIZE_BYTES, &buffer[i2c_buffer_offset_bytes], pcore_results);
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+		i2c_buffer_offset_bytes = 0;
+		status = VL53LX_i2c_decode_system_results(VL53LX_SYSTEM_RESULTS_I2C_SIZE_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 = 0;
+	VL53LX_range_data_t *pdata;
+	int32_t range_mm = 0;
+	uint32_t tmpu32 = 0;
+	uint16_t rpscr_crosstalk_corrected_mcps_sd0;
+	uint16_t rmmo_effective_spads_sd0;
+	uint16_t rmmi_effective_spads_sd0;
+
+	presults->zone_id         = 0;
+	presults->stream_count    = psys->result__stream_count;
+	presults->wrap_dmax_mm    = 0;
+	presults->max_results     = VL53LX_MAX_RANGE_RESULTS;
+	presults->active_results  = 1;
+	rpscr_crosstalk_corrected_mcps_sd0 = psys->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0;
+	rmmo_effective_spads_sd0 = psys->result__mm_outer_actual_effective_spads_sd0;
+	rmmi_effective_spads_sd0 = psys->result__mm_inner_actual_effective_spads_sd0;
+
+	for (i = 0; i < VL53LX_MAX_AMBIENT_DMAX_VALUES; i++)
+		presults->VL53LX_p_022[i] = 0;
+
+	pdata = &(presults->VL53LX_p_003[0]);
+
+	for (i = 0; i < 2; i++) {
+		pdata->range_id     = i;
+		pdata->time_stamp   = 0;
+
+		if ((psys->result__stream_count == 0) && ((psys->result__range_status & VL53LX_RANGE_STATUS__RANGE_STATUS_MASK) == VL53LX_DEVICEERROR_RANGECOMPLETE)) {
+			pdata->range_status = VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK;
+		} else {
+			pdata->range_status = psys->result__range_status & VL53LX_RANGE_STATUS__RANGE_STATUS_MASK;
+		}
+
+		pdata->VL53LX_p_012 = 0;
+		pdata->VL53LX_p_019    = 0;
+		pdata->VL53LX_p_023   = 0;
+		pdata->VL53LX_p_024     = 0;
+		pdata->VL53LX_p_013   = 0;
+		pdata->VL53LX_p_025    = 0;
+
+		switch (i) {
+		case 0:
+			if (psys->result__report_status == VL53LX_DEVICEREPORTSTATUS_MM1)
+				pdata->VL53LX_p_004 = rmmi_effective_spads_sd0;
+			else if (psys->result__report_status == VL53LX_DEVICEREPORTSTATUS_MM2)
+				pdata->VL53LX_p_004 = rmmo_effective_spads_sd0;
+			else
+				pdata->VL53LX_p_004 = psys->result__dss_actual_effective_spads_sd0;
+
+			pdata->peak_signal_count_rate_mcps = rpscr_crosstalk_corrected_mcps_sd0;
+			pdata->avg_signal_count_rate_mcps = psys->result__avg_signal_count_rate_mcps_sd0;
+			pdata->ambient_count_rate_mcps = psys->result__ambient_count_rate_mcps_sd0;
+
+			tmpu32 = ((uint32_t)psys->result__sigma_sd0 << 5);
+			if (tmpu32 > 0xFFFF)
+				tmpu32 = 0xFFFF;
+			pdata->VL53LX_p_002 = (uint16_t)tmpu32;
+			pdata->VL53LX_p_011 = psys->result__phase_sd0;
+
+			range_mm = (int32_t)(psys->result__final_crosstalk_corrected_range_mm_sd0);
+			range_mm *= gain_factor;
+			range_mm += 0x0400;
+			range_mm /= 0x0800;
+
+			pdata->median_range_mm = (int16_t)range_mm;
+			pdata->VL53LX_p_017 = pcore->result_core__ranging_total_events_sd0;
+			pdata->VL53LX_p_010 =                          pcore->result_core__signal_total_events_sd0;
+			pdata->total_periods_elapsed = pcore->result_core__total_periods_elapsed_sd0;
+			pdata->VL53LX_p_016 = pcore->result_core__ambient_window_events_sd0;
+			break;
+		case 1:
+			pdata->VL53LX_p_004 = psys->result__dss_actual_effective_spads_sd1;
+			pdata->peak_signal_count_rate_mcps = psys->result__peak_signal_count_rate_mcps_sd1;
+			pdata->avg_signal_count_rate_mcps = 0xFFFF;
+			pdata->ambient_count_rate_mcps = psys->result__ambient_count_rate_mcps_sd1;
+
+			tmpu32 = ((uint32_t)psys->result__sigma_sd1 << 5);
+			if (tmpu32 > 0xFFFF)
+				tmpu32 = 0xFFFF;
+			pdata->VL53LX_p_002 = (uint16_t)tmpu32;
+			pdata->VL53LX_p_011 = psys->result__phase_sd1;
+
+			range_mm = (int32_t)(psys->result__final_crosstalk_corrected_range_mm_sd1);
+			range_mm *= gain_factor;
+			range_mm += 0x0400;
+			range_mm /= 0x0800;
+
+			pdata->median_range_mm = (int16_t)range_mm;
+			pdata->VL53LX_p_017 = pcore->result_core__ranging_total_events_sd1;
+			pdata->VL53LX_p_010 = pcore->result_core__signal_total_events_sd1;
+			pdata->total_periods_elapsed  = pcore->result_core__total_periods_elapsed_sd1;
+			pdata->VL53LX_p_016 = pcore->result_core__ambient_window_events_sd1;
+			break;
+		}
+
+		pdata->VL53LX_p_026    = pdata->VL53LX_p_011;
+		pdata->VL53LX_p_027    = pdata->VL53LX_p_011;
+		pdata->min_range_mm = pdata->median_range_mm;
+		pdata->max_range_mm = pdata->median_range_mm;
+		pdata++;
+	}
+
+	presults->device_status = VL53LX_DEVICEERROR_NOUPDATE;
+
+	switch (psys->result__range_status & VL53LX_RANGE_STATUS__RANGE_STATUS_MASK) {
+	case VL53LX_DEVICEERROR_VCSELCONTINUITYTESTFAILURE:
+	case VL53LX_DEVICEERROR_VCSELWATCHDOGTESTFAILURE:
+	case VL53LX_DEVICEERROR_NOVHVVALUEFOUND:
+	case VL53LX_DEVICEERROR_USERROICLIP:
+	case VL53LX_DEVICEERROR_MULTCLIPFAIL:
+		presults->device_status = (psys->result__range_status & VL53LX_RANGE_STATUS__RANGE_STATUS_MASK);
+		presults->VL53LX_p_003[0].range_status = VL53LX_DEVICEERROR_NOUPDATE;
+	break;
+	}
+}
+
+VL53LX_Error VL53LX_low_power_auto_setup_manual_calibration(VL53LX_DEV Dev)
+{
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	pdev->low_power_auto_data.saved_vhv_init = pdev->stat_nvm.vhv_config__init;
+	pdev->low_power_auto_data.saved_vhv_timeout = pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound;
+	pdev->stat_nvm.vhv_config__init &= 0x7F;
+	pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound = (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 = 0x01;
+	pdev->low_power_auto_data.first_run_phasecal_result = pdev->dbg_results.phasecal_result__vcsel_start;
+	pdev->gen_cfg.cal_config__vcsel_start = 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 = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_system_results_t *pS = &(pdev->sys_results);
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+	uint32_t utemp32a;
+
+	utemp32a = pS->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 + pS->result__ambient_count_rate_mcps_sd0;
+
+	if (utemp32a > 0xFFFF)
+		utemp32a = 0xFFFF;
+
+	utemp32a = utemp32a << 16;
+
+	if (pdev->sys_results.result__dss_actual_effective_spads_sd0 == 0)
+		status = VL53LX_ERROR_DIVISION_BY_ZERO;
+	else {
+		utemp32a = utemp32a /
+		pdev->sys_results.result__dss_actual_effective_spads_sd0;
+		pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = utemp32a;
+		utemp32a = pdev->stat_cfg.dss_config__target_total_rate_mcps << 16;
+		if (pdev->low_power_auto_data.dss__total_rate_per_spad_mcps == 0)
+			status = VL53LX_ERROR_DIVISION_BY_ZERO;
+		else {
+			utemp32a = utemp32a / pdev->low_power_auto_data.dss__total_rate_per_spad_mcps;
+
+			if (utemp32a > 0xFFFF)
+				utemp32a = 0xFFFF;
+
+			pdev->low_power_auto_data.dss__required_spads = (uint16_t)utemp32a;
+			pdev->gen_cfg.dss_config__manual_effective_spads_select = pdev->low_power_auto_data.dss__required_spads;
+			pdev->gen_cfg.dss_config__roi_mode_control = VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
+		}
+	}
+
+	if (status == VL53LX_ERROR_DIVISION_BY_ZERO) {
+		pdev->low_power_auto_data.dss__required_spads = 0x8000;
+		pdev->gen_cfg.dss_config__manual_effective_spads_select = pdev->low_power_auto_data.dss__required_spads;
+		pdev->gen_cfg.dss_config__roi_mode_control = VL53LX_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
+		status = VL53LX_ERROR_NONE;
+	}
+
+	return status;
+}
+
+VL53LX_Error VL53LX_check_ll_driver_rd_state(VL53LX_DEV Dev)
+{
+	VL53LX_Error         status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t  *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t  *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+	VL53LX_ll_driver_state_t  *pstate       = &(pdev->ll_state);
+	VL53LX_system_results_t   *psys_results = &(pdev->sys_results);
+	VL53LX_histogram_bin_data_t *phist_data = &(pdev->hist_data);
+	VL53LX_zone_private_dyn_cfgs_t *pZ = &(pres->zone_dyn_cfgs);
+
+	uint8_t   device_range_status   = 0;
+	uint8_t   device_stream_count   = 0;
+	uint8_t   device_gph_id         = 0;
+	uint8_t   histogram_mode        = 0;
+	uint8_t   expected_stream_count = 0;
+	uint8_t   expected_gph_id       = 0;
+
+	device_range_status = psys_results->result__range_status & VL53LX_RANGE_STATUS__RANGE_STATUS_MASK;
+	device_stream_count = psys_results->result__stream_count;
+
+	histogram_mode = (pdev->sys_ctrl.system__mode_start & VL53LX_DEVICESCHEDULERMODE_HISTOGRAM) == VL53LX_DEVICESCHEDULERMODE_HISTOGRAM;
+
+	device_gph_id = (psys_results->result__interrupt_status & VL53LX_INTERRUPT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4;
+
+	if (histogram_mode)
+		device_gph_id = (phist_data->result__interrupt_status & VL53LX_INTERRUPT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4;
+
+	if (!((pdev->sys_ctrl.system__mode_start & VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK) == VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK))
+		goto ENDFUNC;
+
+	if (pstate->rd_device_state == VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC) {
+		if (histogram_mode == 0) {
+			if (device_range_status != VL53LX_DEVICEERROR_GPHSTREAMCOUNT0READY)
+				status = VL53LX_ERROR_GPH_SYNC_CHECK_FAIL;
+		}
+	} else {
+		if (pstate->rd_stream_count != device_stream_count)
+			status = VL53LX_ERROR_STREAM_COUNT_CHECK_FAIL;
+
+		if (pstate->rd_gph_id != device_gph_id)
+			status = VL53LX_ERROR_GPH_ID_CHECK_FAIL;
+
+		expected_stream_count = pZ->VL53LX_p_003[pstate->rd_zone_id].expected_stream_count;
+		expected_gph_id = pZ->VL53LX_p_003[pstate->rd_zone_id].expected_gph_id;
+
+		if (expected_stream_count != device_stream_count) {
+			if (!((pdev->zone_cfg.active_zones == 0) && (device_stream_count == 255)))
+				status = VL53LX_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL;
+		}
+
+		if (expected_gph_id != device_gph_id)
+			status = VL53LX_ERROR_ZONE_GPH_ID_CHECK_FAIL;
+	}
+
+ENDFUNC:
+	return status;
+}
+
+VL53LX_Error VL53LX_get_device_results(VL53LX_DEV Dev, VL53LX_DeviceResultsLevel device_results_level, VL53LX_range_results_t *prange_results)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_LLDriverResults_t *pres = VL53LXDevStructGetLLResultsHandle(Dev);
+	VL53LX_range_results_t *presults = &(pres->range_results);
+	VL53LX_zone_objects_t *pobjects = &(pres->zone_results.VL53LX_p_003[0]);
+	VL53LX_ll_driver_state_t *pstate = &(pdev->ll_state);
+	VL53LX_zone_config_t *pzone_cfg = &(pdev->zone_cfg);
+	VL53LX_zone_hist_info_t *phist_info = &(pres->zone_hists.VL53LX_p_003[0]);
+	VL53LX_dmax_calibration_data_t   dmax_cal;
+	VL53LX_dmax_calibration_data_t *pdmax_cal = &dmax_cal;
+	VL53LX_hist_post_process_config_t *pHP = &(pdev->histpostprocess);
+	VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
+	VL53LX_low_power_auto_data_t *pL = &(pdev->low_power_auto_data);
+	VL53LX_histogram_bin_data_t *pHD = &(pdev->hist_data);
+	VL53LX_customer_nvm_managed_t *pN = &(pdev->customer);
+	VL53LX_zone_histograms_t *pZH = &(pres->zone_hists);
+	VL53LX_xtalk_calibration_results_t *pXCR = &(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_HISTOGRAM) == VL53LX_DEVICESCHEDULERMODE_HISTOGRAM) {
+		status = VL53LX_get_histogram_bin_data(Dev, &(pdev->hist_data));
+		if (status == VL53LX_ERROR_NONE &&
+			pHD->number_of_ambient_bins == 0) {
+			zid = pdev->ll_state.rd_zone_id;
+			status = VL53LX_hist_copy_and_scale_ambient_info(&(pZH->VL53LX_p_003[zid]), &(pdev->hist_data));
+		}
+		if (status != VL53LX_ERROR_NONE)
+			goto UPDATE_DYNAMIC_CONFIG;
+
+		VL53LX_compute_histo_merge_nb(Dev, &histo_merge_nb);
+		if (histo_merge_nb == 0)
+			histo_merge_nb = 1;
+		idx = histo_merge_nb - 1;
+		if (pdev->tuning_parms.tp_hist_merge == 1)
+			pC->algo__crosstalk_compensation_plane_offset_kcps = pXCR->algo__xtalk_cpo_HistoMerge_kcps[idx];
+
+		pHP->gain_factor = pdev->gain_cal.histogram_ranging_gain_factor;
+
+		pHP->algo__crosstalk_compensation_plane_offset_kcps = VL53LX_calc_crosstalk_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 = pC->algo__crosstalk_compensation_x_plane_gradient_kcps;
+		pHP->algo__crosstalk_compensation_y_plane_gradient_kcps = pC->algo__crosstalk_compensation_y_plane_gradient_kcps;
+
+		pdev->dmax_cfg.ambient_thresh_sigma = pHP->ambient_thresh_sigma1;
+		pdev->dmax_cfg.min_ambient_thresh_events = pHP->min_ambient_thresh_events;
+		pdev->dmax_cfg.signal_total_events_limit = pHP->signal_total_events_limit;
+		pdev->dmax_cfg.dss_config__target_total_rate_mcps = pdev->stat_cfg.dss_config__target_total_rate_mcps;
+		pdev->dmax_cfg.dss_config__aperture_attenuation = pdev->gen_cfg.dss_config__aperture_attenuation;
+
+		pHP->algo__crosstalk_detect_max_valid_range_mm = pC->algo__crosstalk_detect_max_valid_range_mm;
+		pHP->algo__crosstalk_detect_min_valid_range_mm = pC->algo__crosstalk_detect_min_valid_range_mm;
+		pHP->algo__crosstalk_detect_max_valid_rate_kcps = pC->algo__crosstalk_detect_max_valid_rate_kcps;
+		pHP->algo__crosstalk_detect_max_sigma_mm = 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 = 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 *= 4;
+			break;
+		default:
+			pHP->range_offset_mm = 0;
+			break;
+		}
+
+		if (status != 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 = VL53LX_get_dmax_calibration_data(Dev, pdev->dmax_mode, pdmax_cal);
+
+		if (status != VL53LX_ERROR_NONE)
+			goto UPDATE_DYNAMIC_CONFIG;
+
+		status = 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 == 1) &&
+			(histo_merge_nb > 1))
+		for (i = 0; i < VL53LX_MAX_RANGE_RESULTS; i++) {
+			pdata = &(presults->VL53LX_p_003[i]);
+			pdata->VL53LX_p_016 /= histo_merge_nb;
+			pdata->VL53LX_p_017 /= histo_merge_nb;
+			pdata->VL53LX_p_010 /= histo_merge_nb;
+			pdata->peak_signal_count_rate_mcps /= histo_merge_nb;
+			pdata->avg_signal_count_rate_mcps /= histo_merge_nb;
+			pdata->ambient_count_rate_mcps /= histo_merge_nb;
+			pdata->VL53LX_p_009 /= histo_merge_nb;
+		}
+
+		if (status != VL53LX_ERROR_NONE)
+			goto UPDATE_DYNAMIC_CONFIG;
+
+		status = VL53LX_hist_wrap_dmax(&(pdev->histpostprocess), &(pdev->hist_data), &(presults->wrap_dmax_mm));
+
+		if (status != VL53LX_ERROR_NONE)
+			goto UPDATE_DYNAMIC_CONFIG;
+
+		zid = pdev->ll_state.rd_zone_id;
+		status = VL53LX_hist_phase_consistency_check(Dev, &(pZH->VL53LX_p_003[zid]), &(pres->zone_results.VL53LX_p_003[zid]), presults);
+
+		if (status != VL53LX_ERROR_NONE)
+			goto UPDATE_DYNAMIC_CONFIG;
+
+		zid = pdev->ll_state.rd_zone_id;
+		status = VL53LX_hist_xmonitor_consistency_check(Dev, &(pZH->VL53LX_p_003[zid]), &(pres->zone_results.VL53LX_p_003[zid]), &(presults->xmonitor));
+
+		if (status != VL53LX_ERROR_NONE)
+			goto UPDATE_DYNAMIC_CONFIG;
+
+		zid = pdev->ll_state.rd_zone_id;
+		pZH->max_zones    = VL53LX_MAX_USER_ZONES;
+		pZH->active_zones = pdev->zone_cfg.active_zones+1;
+		pHD->zone_id       = zid;
+
+		if (zid < pres->zone_results.max_zones) {
+			phist_info = &(pZH->VL53LX_p_003[zid]);
+			phist_info->rd_device_state = pHD->rd_device_state;
+			phist_info->number_of_ambient_bins = pHD->number_of_ambient_bins;
+			phist_info->result__dss_actual_effective_spads = pHD->result__dss_actual_effective_spads;
+			phist_info->VL53LX_p_005 = pHD->VL53LX_p_005;
+			phist_info->total_periods_elapsed = pHD->total_periods_elapsed;
+			phist_info->ambient_events_sum = pHD->ambient_events_sum;
+		}
+
+		if (status != 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 != VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC) {
+				if (status == VL53LX_ERROR_NONE) {
+					status = VL53LX_dynamic_zone_update(Dev, presults);
+				}
+			}
+
+			for (i = 0; i < VL53LX_MAX_USER_ZONES; i++) {
+				pzone_cfg->bin_config[i] = ((pdev->ll_state.cfg_internal_stream_count) & 0x01) ? VL53LX_ZONECONFIG_BINCONFIG__HIGHAMB : VL53LX_ZONECONFIG_BINCONFIG__LOWAMB;
+			}
+
+			if (status == VL53LX_ERROR_NONE)
+				status = VL53LX_multizone_hist_bins_update(Dev);
+		}
+
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_dynamic_xtalk_correction_corrector(Dev);
+
+		if (pdev->tuning_parms.tp_hist_merge == 1)
+			pC->algo__crosstalk_compensation_plane_offset_kcps = pXCR->algo__xtalk_cpo_HistoMerge_kcps[0];
+	} else {
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_get_measurement_results(Dev, device_results_level);
+
+		if (status == VL53LX_ERROR_NONE)
+			VL53LX_copy_sys_and_core_results_to_range_results((int32_t)pdev->gain_cal.standard_ranging_gain_factor, &(pdev->sys_results), &(pdev->core_results), presults);
+
+		if (pL->is_low_power_auto_mode == 1) {
+			if ((status == VL53LX_ERROR_NONE) && (pL->low_power_auto_range_count == 0)) {
+				status = VL53LX_low_power_auto_setup_manual_calibration(Dev);
+				pL->low_power_auto_range_count = 1;
+			} else if ((status == VL53LX_ERROR_NONE) && (pL->low_power_auto_range_count == 1)) {
+				pL->low_power_auto_range_count = 2;
+			}
+
+			if ((pL->low_power_auto_range_count != 0xFF) && (status == VL53LX_ERROR_NONE)) {
+				status = VL53LX_low_power_auto_update_DSS(Dev);
+			}
+		}
+	}
+
+	presults->cfg_device_state = pdev->ll_state.cfg_device_state;
+	presults->rd_device_state  = pdev->ll_state.rd_device_state;
+	presults->zone_id          = pdev->ll_state.rd_zone_id;
+
+	if (status == VL53LX_ERROR_NONE) {
+		pres->zone_results.max_zones    = VL53LX_MAX_USER_ZONES;
+		pres->zone_results.active_zones = pdev->zone_cfg.active_zones+1;
+		zid = pdev->ll_state.rd_zone_id;
+
+		if (zid < pres->zone_results.max_zones) {
+			pobjects = &(pres->zone_results.VL53LX_p_003[zid]);
+			pobjects->cfg_device_state  = presults->cfg_device_state;
+			pobjects->rd_device_state   = presults->rd_device_state;
+			pobjects->zone_id           = presults->zone_id;
+			pobjects->stream_count      = presults->stream_count;
+
+			pobjects->xmonitor.VL53LX_p_016 = presults->xmonitor.VL53LX_p_016;
+			pobjects->xmonitor.VL53LX_p_017 = presults->xmonitor.VL53LX_p_017;
+			pobjects->xmonitor.VL53LX_p_011 = presults->xmonitor.VL53LX_p_011;
+			pobjects->xmonitor.range_status = presults->xmonitor.range_status;
+
+			pobjects->max_objects      = presults->max_results;
+			pobjects->active_objects   = presults->active_results;
+
+			for (i = 0; i < presults->active_results; i++) {
+				pobjects->VL53LX_p_003[i].VL53LX_p_016 = presults->VL53LX_p_003[i].VL53LX_p_016;
+				pobjects->VL53LX_p_003[i].VL53LX_p_017 = presults->VL53LX_p_003[i].VL53LX_p_017;
+				pobjects->VL53LX_p_003[i].VL53LX_p_011 = presults->VL53LX_p_003[i].VL53LX_p_011;
+				pobjects->VL53LX_p_003[i].range_status = presults->VL53LX_p_003[i].range_status;
+			}
+		}
+	}
+
+	memcpy(prange_results, presults, sizeof(VL53LX_range_results_t));
+
+	if (status == VL53LX_ERROR_NONE)
+		status = 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 = VL53LX_RANGESTATUS_OUTOFBOUNDS_FAIL;
+		break;
+	case VL53LX_DEVICEERROR_SIGMATHRESHOLDCHECK:
+		RangeStatus = VL53LX_RANGESTATUS_SIGMA_FAIL;
+		break;
+	case VL53LX_DEVICEERROR_RANGECOMPLETE_NO_WRAP_CHECK:
+		RangeStatus = VL53LX_RANGESTATUS_RANGE_VALID_NO_WRAP_CHECK_FAIL;
+		break;
+	case VL53LX_DEVICEERROR_PHASECONSISTENCY:
+		RangeStatus = VL53LX_RANGESTATUS_WRAP_TARGET_FAIL;
+		break;
+	case VL53LX_DEVICEERROR_PREV_RANGE_NO_TARGETS:
+		RangeStatus = VL53LX_RANGESTATUS_TARGET_PRESENT_LACK_OF_SIGNAL;
+		break;
+	case VL53LX_DEVICEERROR_EVENTCONSISTENCY:
+		RangeStatus = VL53LX_RANGESTATUS_WRAP_TARGET_FAIL;
+		break;
+	case VL53LX_DEVICEERROR_RANGECOMPLETE_MERGED_PULSE:
+		RangeStatus = VL53LX_RANGESTATUS_RANGE_VALID_MERGED_PULSE;
+		break;
+	case VL53LX_DEVICEERROR_RANGECOMPLETE:
+		RangeStatus = VL53LX_RANGESTATUS_RANGE_VALID;
+		break;
+	default:
+		RangeStatus = 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 = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_tuning_parm_storage_t *tp = &(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 = 0;
+	uint8_t uwr_status;
+	int16_t AddOffset;
+
+	SUPPRESS_UNUSED_WARNING(Dev);
+
+	FilteredRangeStatus = presults_data->range_status & 0x1F;
+
+	SignalRate = VL53LX_FIXPOINT97TOFIXPOINT1616(presults_data->peak_signal_count_rate_mcps);
+	pRangeData->SignalRateRtnMegaCps = SignalRate;
+
+	AmbientRate = VL53LX_FIXPOINT97TOFIXPOINT1616(presults_data->ambient_count_rate_mcps);
+	pRangeData->AmbientRateRtnMegaCps = AmbientRate;
+
+	TempFix1616 = VL53LX_FIXPOINT97TOFIXPOINT1616(presults_data->VL53LX_p_002);
+
+	pRangeData->SigmaMilliMeter = TempFix1616;
+
+	pRangeData->RangeMilliMeter = presults_data->median_range_mm;
+	pRangeData->RangeMaxMilliMeter = presults_data->max_range_mm;
+	pRangeData->RangeMinMilliMeter = 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 =  VL53LX_RANGESTATUS_HARDWARE_FAIL;
+		break;
+	case VL53LX_DEVICEERROR_USERROICLIP:
+		pRangeData->RangeStatus =  VL53LX_RANGESTATUS_MIN_RANGE_FAIL;
+		break;
+	default:
+		pRangeData->RangeStatus =  VL53LX_RANGESTATUS_RANGE_VALID;
+	}
+
+	if ((pRangeData->RangeStatus ==  VL53LX_RANGESTATUS_RANGE_VALID) && (active_results == 0)) {
+		pRangeData->RangeStatus = VL53LX_RANGESTATUS_NONE;
+		pRangeData->SignalRateRtnMegaCps = 0;
+		pRangeData->SigmaMilliMeter = 0;
+		pRangeData->RangeMilliMeter = 8191;
+		pRangeData->RangeMaxMilliMeter = 8191;
+		pRangeData->RangeMinMilliMeter = 8191;
+	}
+
+	if (pRangeData->RangeStatus ==  VL53LX_RANGESTATUS_RANGE_VALID)
+		pRangeData->RangeStatus = ConvertStatusHisto(FilteredRangeStatus);
+
+	VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_UWR_ENABLE, &ExtendedRangeEnabled);
+
+	sequency = streamcount % 2;
+	uwr_status = 0;
+	RangeMillimeterInit = pRangeData->RangeMilliMeter;
+	AddOffset = 0;
+
+	pRangeData->ExtendedRange = 0;
+
+	if ((active_results != 1) || (pdev->PreviousRangeActiveResults != 1))
+		ExtendedRangeEnabled = 0;
+
+	if (ExtendedRangeEnabled &&
+		(pRangeData->RangeStatus ==
+			VL53LX_RANGESTATUS_WRAP_TARGET_FAIL ||
+			pRangeData->RangeStatus ==
+			VL53LX_RANGESTATUS_OUTOFBOUNDS_FAIL)
+		&& (pdev->PreviousRangeStatus[iteration] ==
+			VL53LX_RANGESTATUS_WRAP_TARGET_FAIL ||
+			pdev->PreviousRangeStatus[iteration] ==
+			VL53LX_RANGESTATUS_OUTOFBOUNDS_FAIL ||
+			(pdev->PreviousRangeStatus[iteration] ==
+			VL53LX_RANGESTATUS_RANGE_VALID &&
+			pdev->PreviousExtendedRange[iteration] == 1))) {
+		if (((pdev->PreviousStreamCount) == (pdev->hist_data.result__stream_count - 1)) || ((pdev->PreviousStreamCount) == (pdev->hist_data.result__stream_count + 127))) {
+			RangeDiff = pRangeData->RangeMilliMeter - pdev->PreviousRangeMilliMeter[iteration];
+			uwr_status = 1;
+			switch (pdev->preset_mode) {
+			case VL53LX_DEVICEPRESETMODE_HISTOGRAM_SHORT_RANGE:
+				uwr_status = 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 == 1) {
+					AddOffset =
+					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 == 0) {
+					AddOffset = tp->tp_uwr_med_corr_z_1_rangea;
+				} else if (RangeDiff > tp->tp_uwr_med_z_2_min && RangeDiff < tp->tp_uwr_med_z_2_max && sequency == 0) {
+					AddOffset = 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 == 1) {
+					AddOffset = tp->tp_uwr_med_corr_z_2_rangeb;
+				} else if (RangeDiff > tp->tp_uwr_med_z_3_min && RangeDiff < tp->tp_uwr_med_z_3_max && sequency == 1) {
+					AddOffset = 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 == 0) {
+					AddOffset = tp->tp_uwr_med_corr_z_3_rangea;
+				} else if (RangeDiff > tp->tp_uwr_med_z_4_min && RangeDiff < tp->tp_uwr_med_z_4_max && sequency == 0) {
+					AddOffset = 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 == 1) {
+					AddOffset = tp->tp_uwr_med_corr_z_4_rangeb;
+				} else if (RangeDiff < tp->tp_uwr_med_z_5_max && RangeDiff > tp->tp_uwr_med_z_5_min) {
+					AddOffset = tp->tp_uwr_med_corr_z_5_rangea;
+				} else
+					uwr_status = 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 == 0) {
+					AddOffset = 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 == 1) {
+					AddOffset = tp->tp_uwr_lng_corr_z_1_rangeb;
+				} else if (RangeDiff > tp->tp_uwr_lng_z_2_min && RangeDiff < tp->tp_uwr_lng_z_2_max && sequency == 1) {
+					AddOffset = 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 == 0) {
+					AddOffset = tp->tp_uwr_lng_corr_z_2_rangea;
+				} else if (RangeDiff < tp->tp_uwr_lng_z_3_max && RangeDiff > tp->tp_uwr_lng_z_3_min) {
+					AddOffset = tp->tp_uwr_lng_corr_z_3_rangea;
+				} else
+					uwr_status = 0;
+				break;
+			default:
+				uwr_status = 0;
+				break;
+			}
+		}
+
+		if (uwr_status) {
+			pRangeData->RangeMilliMeter += AddOffset;
+			pRangeData->RangeMinMilliMeter += AddOffset;
+			pRangeData->RangeMaxMilliMeter += AddOffset;
+			pRangeData->ExtendedRange = 1;
+			pRangeData->RangeStatus = 0;
+		}
+
+	}
+
+	pdev->PreviousRangeMilliMeter[iteration] = RangeMillimeterInit;
+	pdev->PreviousRangeStatus[iteration] = pRangeData->RangeStatus;
+	pdev->PreviousExtendedRange[iteration] = pRangeData->ExtendedRange;
+	pdev->PreviousRangeActiveResults = active_results;
+
+	Range = pRangeData->RangeMilliMeter;
+	if ((pRangeData->RangeStatus ==  VL53LX_RANGESTATUS_RANGE_VALID) && (Range < 0)) {
+		if (Range < BDTable[VL53LX_TUNING_PROXY_MIN])
+			pRangeData->RangeStatus = VL53LX_RANGESTATUS_RANGE_INVALID;
+		else
+			pRangeData->RangeMilliMeter = 0;
+	}
+
+	return Status;
+}
+
+static VL53LX_Error SetMeasurementData(VL53LX_DEV Dev, VL53LX_range_results_t *presults, VL53LX_MultiRangingData_t *pMultiRangingData)
+{
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	uint8_t i;
+	uint8_t iteration;
+	VL53LX_TargetRangeData_t *pRangeData;
+	VL53LX_range_data_t *presults_data;
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+	uint8_t ActiveResults;
+
+	pMultiRangingData->NumberOfObjectsFound = presults->active_results;
+	pMultiRangingData->HasXtalkValueChanged = presults->smudge_corrector_data.new_xtalk_applied_flag;
+
+	pMultiRangingData->TimeStamp = 0;
+
+	pMultiRangingData->StreamCount = presults->stream_count;
+
+	ActiveResults = presults->active_results;
+	if (ActiveResults < 1)
+		iteration = 1;
+	else
+		iteration = ActiveResults;
+	for (i = 0; i < iteration; i++) {
+		pRangeData = &(pMultiRangingData->RangeData[i]);
+		presults_data = &(presults->VL53LX_p_003[i]);
+		if (Status == VL53LX_ERROR_NONE)
+			Status = SetTargetData(Dev, ActiveResults, pMultiRangingData->StreamCount, i, presults->device_status, presults_data, pRangeData);
+
+		pMultiRangingData->EffectiveSpadRtnCount = presults_data->VL53LX_p_004;
+	}
+	pdev->PreviousStreamCount = pdev->hist_data.result__stream_count;
+	for (i = iteration; i < VL53LX_MAX_RANGE_RESULTS; i++) {
+		pdev->PreviousRangeMilliMeter[i] = 0;
+		pdev->PreviousRangeStatus[i] = 255;
+		pdev->PreviousExtendedRange[i] = 0;
+	}
+
+	return Status;
+}
+
+static void stmvl53lx_work_handler(struct work_struct *work)
+{
+	struct stmvl53lx_data *data;
+
+	data = 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 = -ENODEV;
+		goto done;
+	}
+	rc = copy_from_user(&roi, p, sizeof(roi));
+	if (rc) {
+		rc = -EFAULT;
+		goto done;
+	}
+
+	if (roi.is_read) {
+		memcpy(&roi.Roi, &data->roi_cfg, sizeof(roi.Roi));
+		rc = copy_to_user(p, &roi, sizeof(roi));
+		if (rc) {
+			vl53lx_errmsg("fail to copy Roi to user %d", rc);
+			rc = -EFAULT;
+			goto done;
+		}
+	} else {
+		if (data->enable_sensor) {
+			rc = -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->roi_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 == pid)
+			return true;
+
+	return false;
+}
+
+static bool is_new_data_for_me(struct stmvl53lx_data *data, pid_t pid, struct 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 pid, struct list_head *head)
+{
+	bool res;
+
+	mutex_lock(&data->work_mutex);
+	res = 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 list_head *head)
+{
+	int rc = 0;
+
+	mutex_unlock(&data->work_mutex);
+	rc = wait_event_interruptible_timeout(data->waiter_for_data, sleep_for_data_condition(data, pid, head), usecs_to_jiffies(2 * data->timing_budget));
+	if (rc == 0)
+		rc = -EAGAIN;
+	else
+		rc = 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 = kmalloc(sizeof(struct stmvl53lx_waiters), GFP_KERNEL);
+	if (!new_waiter)
+		return -ENOMEM;
+	new_waiter->pid = 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 = 0;
+	int rc0;
+	struct stmvl53lx_data_with_additional __user *d = p;
+	pid_t pid = current->pid;
+
+	mutex_lock(&data->work_mutex);
+	if (data->is_device_remove) {
+		rc = -ENODEV;
+		goto done;
+	}
+	if (!data->enable_sensor) {
+		rc = -ENODEV;
+		goto done;
+	}
+	if (!is_new_data_for_me(data, pid, &data->mz_data_reader_list))
+		rc = sleep_for_data(data, pid, &data->mz_data_reader_list);
+	if (rc) {
+		kill_mz_data(&data->meas.multi_range_data);
+		rc0 = copy_to_user(&d->data, &data->meas.multi_range_data, sizeof(VL53LX_MultiRangingData_t));
+		goto done;
+	}
+
+	rc = copy_to_user(&d->data, &data->meas.multi_range_data, sizeof(VL53LX_MultiRangingData_t));
+	if (rc)
+		goto done;
+	if (is_additional) {
+		rc = copy_to_user(&d->additional_data, &data->meas.additional_data, sizeof(VL53LX_AdditionalData_t));
+		if (rc)
+			goto done;
+	}
+	rc = 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 = p;
+	int rc = 0;
+
+	mutex_lock(&data->work_mutex);
+	if (data->is_device_remove) {
+		rc = -ENODEV;
+		goto done;
+	}
+	rc = 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 = -EFAULT;
+		goto done;
+	}
+	if (is_additional) {
+		rc = copy_to_user(&d->additional_data, &data->meas.additional_data, sizeof(VL53LX_AdditionalData_t));
+		if (rc) {
+			vl53lx_dbgmsg("copy to user fail %d", rc);
+			rc = -EFAULT;
+			goto done;
+		}
+	}
+	if (!data->enable_sensor)
+		rc = -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 = 0;
+	struct stmvl53lx_ioctl_calibration_data_t calib;
+	int data_offset = offsetof(struct stmvl53lx_ioctl_calibration_data_t, data);
+
+	mutex_lock(&data->work_mutex);
+
+	if (data->is_device_remove) {
+		rc = -ENODEV;
+		goto done;
+	}
+	rc = copy_from_user(&calib, p, data_offset);
+	if (rc) {
+		vl53lx_errmsg("fail to detect read or write %d", rc);
+		rc = -EFAULT;
+		goto done;
+	}
+
+	if (calib.is_read) {
+		memset(&calib.data, 0, sizeof(calib.data));
+		rc = VL53LX_GetCalibrationData(&data->stdev, &calib.data);
+		if (rc) {
+			vl53lx_errmsg("VL53LX_GetCalibrationData fail %d", rc);
+			rc = store_last_error(data, rc);
+			goto done;
+		}
+		rc = copy_to_user(p + data_offset, &calib.data,
+			sizeof(calib.data));
+	} else {
+		if (data->enable_sensor) {
+			rc = -EBUSY;
+			vl53lx_errmsg("can't set calib data while ranging\n");
+			goto done;
+		}
+		rc = copy_from_user(&calib.data, p + data_offset,
+			sizeof(calib.data));
+		if (rc) {
+			vl53lx_errmsg("fail to copy calib data");
+			rc = -EFAULT;
+			goto done;
+		}
+		rc = VL53LX_SetCalibrationData(&data->stdev, &calib.data);
+		if (rc) {
+			vl53lx_errmsg("VL53LX_SetCalibrationData fail %d", rc);
+			rc = 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 = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	uint8_t buffer[2];
+
+	uint32_t macro_period_us = 0;
+	uint32_t timeout_mclks   = 0;
+
+	macro_period_us = VL53LX_calc_macro_period_us(fast_osc_frequency, vcsel_period_a);
+	if (macro_period_us == 0)
+		macro_period_us = 1;
+
+	timeout_mclks = phasecal_timeout_us << 12;
+	timeout_mclks = timeout_mclks + (macro_period_us>>1);
+	timeout_mclks = timeout_mclks / macro_period_us;
+
+	if (timeout_mclks > 0xFF)
+		pdev->gen_cfg.phasecal_config__timeout_macrop = 0xFF;
+	else
+		pdev->gen_cfg.phasecal_config__timeout_macrop = (uint8_t)timeout_mclks;
+
+	pdev->tim_cfg.range_config__vcsel_period_a = vcsel_period_a;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_PHASECAL_CONFIG__TIMEOUT_MACROP, pdev->gen_cfg.phasecal_config__timeout_macrop);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrByte(Dev, VL53LX_RANGE_CONFIG__VCSEL_PERIOD_A, pdev->tim_cfg.range_config__vcsel_period_a);
+
+	buffer[0] = pdev->tim_cfg.range_config__vcsel_period_a;
+	buffer[1] = pdev->tim_cfg.range_config__vcsel_period_a;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WriteMulti(Dev, VL53LX_SD_CONFIG__WOI_SD0, buffer, 2);
+
+	pdev->customer.ref_spad_char__total_rate_target_mcps = total_rate_target_mcps;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrWord(Dev, VL53LX_REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS, total_rate_target_mcps);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrWord(Dev, VL53LX_RANGE_CONFIG__SIGMA_THRESH, max_count_rate_rtn_limit_mcps);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WrWord(Dev, VL53LX_RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_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 = VL53LX_ERROR_NONE;
+
+	if (status == VL53LX_ERROR_NONE) {
+		status = VL53LX_WrByte(Dev, VL53LX_TEST_MODE__CTRL, test_mode__ctrl);
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_poll_for_range_completion(VL53LX_DEV Dev, uint32_t timeout_ms)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	uint8_t  gpio__mux_active_high_hv = 0;
+	uint8_t  interrupt_ready          = 0;
+
+	gpio__mux_active_high_hv = pdev->stat_cfg.gpio_hv_mux__ctrl & VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_MASK;
+
+	if (gpio__mux_active_high_hv == VL53LX_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH)
+		interrupt_ready = 0x01;
+	else
+		interrupt_ready = 0x00;
+
+	status = VL53LX_WaitValueMaskEx(Dev, timeout_ms, VL53LX_GPIO__TIO_HV_STATUS, interrupt_ready, 0x01, VL53LX_POLLING_DELAY_MS);
+	return status;
+}
+
+VL53LX_Error VL53LX_wait_for_test_completion(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	uint8_t data_ready  = 0;
+
+	if (pdev->wait_method == VL53LX_WAIT_METHOD_BLOCKING) {
+		status = VL53LX_poll_for_range_completion(Dev, VL53LX_TEST_COMPLETION_POLLING_TIMEOUT_MS);
+
+	} else {
+		data_ready = 0;
+		while (data_ready == 0x00 && status == VL53LX_ERROR_NONE) {
+			status = VL53LX_is_new_data_ready(Dev, &data_ready);
+			if (status == VL53LX_ERROR_NONE) {
+				status = VL53LX_WaitMs(Dev, VL53LX_POLLING_DELAY_MS);
+			}
+		}
+	}
+	return status;
+}
+
+VL53LX_Error VL53LX_clear_interrupt(VL53LX_DEV Dev)
+{
+	VL53LX_Error status       = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	pdev->sys_ctrl.system__interrupt_clear = VL53LX_CLEAR_RANGE_INT;
+
+	status = VL53LX_WrByte(Dev, VL53LX_SYSTEM__INTERRUPT_CLEAR, pdev->sys_ctrl.system__interrupt_clear);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_run_device_test(VL53LX_DEV Dev, VL53LX_DeviceTestMode device_test_mode)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	uint8_t      comms_buffer[2];
+	uint8_t      gpio_hv_mux__ctrl = 0;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_RdByte(Dev, VL53LX_GPIO_HV_MUX__CTRL, &gpio_hv_mux__ctrl);
+
+	if (status == VL53LX_ERROR_NONE)
+		pdev->stat_cfg.gpio_hv_mux__ctrl = gpio_hv_mux__ctrl;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_start_test(Dev, device_test_mode);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_wait_for_test_completion(Dev);
+
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_ReadMulti(Dev, VL53LX_RESULT__RANGE_STATUS, comms_buffer, 2);
+
+	if (status == VL53LX_ERROR_NONE) {
+		pdev->sys_results.result__range_status  = comms_buffer[0];
+		pdev->sys_results.result__report_status = comms_buffer[1];
+	}
+
+	pdev->sys_results.result__range_status &= VL53LX_RANGE_STATUS__RANGE_STATUS_MASK;
+
+	if (status == VL53LX_ERROR_NONE) {
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_clear_interrupt(Dev);
+	}
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_start_test(Dev, 0x00);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_run_ref_spad_char(VL53LX_DEV Dev, VL53LX_Error *pcal_status)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	uint8_t comms_buffer[6];
+
+	VL53LX_refspadchar_config_t *prefspadchar  = &(pdev->refspadchar);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_enable_powerforce(Dev);
+
+	if (status == VL53LX_ERROR_NONE)
+		status =
+		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 == VL53LX_ERROR_NONE)
+		status = VL53LX_run_device_test(Dev, prefspadchar->device_test_mode);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_ReadMulti(Dev, VL53LX_REF_SPAD_CHAR_RESULT__NUM_ACTUAL_REF_SPADS, comms_buffer, 2);
+
+	if (status == VL53LX_ERROR_NONE) {
+		pdev->dbg_results.ref_spad_char_result__num_actual_ref_spads = comms_buffer[0];
+		pdev->dbg_results.ref_spad_char_result__ref_location = comms_buffer[1];
+	}
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WriteMulti(Dev, VL53LX_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS, comms_buffer, 2);
+
+	if (status == VL53LX_ERROR_NONE) {
+		pdev->customer.ref_spad_man__num_requested_ref_spads = comms_buffer[0];
+		pdev->customer.ref_spad_man__ref_location = comms_buffer[1];
+	}
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_ReadMulti(Dev, VL53LX_RESULT__SPARE_0_SD1, comms_buffer, 6);
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_WriteMulti(Dev, VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0, comms_buffer, 6);
+
+	if (status == VL53LX_ERROR_NONE) {
+		pdev->customer.global_config__spad_enables_ref_0 = comms_buffer[0];
+		pdev->customer.global_config__spad_enables_ref_1 = comms_buffer[1];
+		pdev->customer.global_config__spad_enables_ref_2 = comms_buffer[2];
+		pdev->customer.global_config__spad_enables_ref_3 = comms_buffer[3];
+		pdev->customer.global_config__spad_enables_ref_4 = comms_buffer[4];
+		pdev->customer.global_config__spad_enables_ref_5 = comms_buffer[5];
+	}
+
+	if (status == VL53LX_ERROR_NONE) {
+		switch (pdev->sys_results.result__range_status) {
+		case VL53LX_DEVICEERROR_REFSPADCHARNOTENOUGHDPADS:
+			status = VL53LX_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS;
+			break;
+		case VL53LX_DEVICEERROR_REFSPADCHARMORETHANTARGET:
+			status = VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH;
+			break;
+		case VL53LX_DEVICEERROR_REFSPADCHARLESSTHANTARGET:
+			status = VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW;
+			break;
+		}
+	}
+	*pcal_status = status;
+	IGNORE_STATUS(IGNORE_REF_SPAD_CHAR_NOT_ENOUGH_SPADS, VL53LX_WARNING_REF_SPAD_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 = VL53LX_ERROR_NONE;
+	VL53LX_Error RawStatus;
+	uint8_t dcrbuffer[24];
+	uint8_t *commbuf;
+	uint8_t numloc[2] = {5, 3};
+	VL53LX_LLDriverData_t *pdev;
+	VL53LX_customer_nvm_managed_t *pc;
+	VL53LX_DistanceModes DistanceMode;
+
+	pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	pc = &pdev->customer;
+
+	if (Status == VL53LX_ERROR_NONE) {
+		DistanceMode = VL53LXDevDataGet(Dev, CurrentParameters.DistanceMode);
+		Status = VL53LX_run_ref_spad_char(Dev, &RawStatus);
+
+		if (Status == VL53LX_ERROR_NONE)
+			Status = VL53LX_SetDistanceMode(Dev, DistanceMode);
+	}
+
+	if (Status == VL53LX_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH) {
+		Status = VL53LX_read_nvm_raw_data(Dev, (uint8_t)(0xA0 >> 2), (uint8_t)(24 >> 2), dcrbuffer);
+
+		if (Status == VL53LX_ERROR_NONE)
+			Status = VL53LX_WriteMulti(Dev, VL53LX_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS, numloc, 2);
+
+		if (Status == VL53LX_ERROR_NONE) {
+			pc->ref_spad_man__num_requested_ref_spads = numloc[0];
+			pc->ref_spad_man__ref_location = numloc[1];
+		}
+		commbuf = &dcrbuffer[16];
+
+		if (Status == VL53LX_ERROR_NONE)
+			Status = VL53LX_WriteMulti(Dev, VL53LX_GLOBAL_CONFIG__SPAD_ENABLES_REF_0, commbuf, 6);
+
+		if (Status == VL53LX_ERROR_NONE) {
+			pc->global_config__spad_enables_ref_0 = commbuf[0];
+			pc->global_config__spad_enables_ref_1 = commbuf[1];
+			pc->global_config__spad_enables_ref_2 = commbuf[2];
+			pc->global_config__spad_enables_ref_3 = commbuf[3];
+			pc->global_config__spad_enables_ref_4 = commbuf[4];
+			pc->global_config__spad_enables_ref_5 = commbuf[5];
+		}
+	}
+	return Status;
+}
+
+static int ctrl_perform_calibration_ref_spad_lock(struct stmvl53lx_data *data, struct stmvl53lx_ioctl_perform_calibration_t *calib)
+{
+	int rc = VL53LX_PerformRefSpadManagement(&data->stdev);
+
+	if (rc) {
+		vl53lx_errmsg("VL53LX_PerformRefSpadManagement fail => %d", rc);
+		rc = 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 = 0;
+
+	pxtalk_data->sample_count             = 0U;
+	pxtalk_data->pll_period_mm            = 0U;
+	pxtalk_data->peak_duration_us_sum     = 0U;
+	pxtalk_data->effective_spad_count_sum = 0U;
+	pxtalk_data->zero_distance_phase_sum  = 0U;
+	pxtalk_data->zero_distance_phase_avg  = 0U;
+	pxtalk_data->event_scaler_sum         = 0U;
+	pxtalk_data->event_scaler_avg         = 4096U;
+	pxtalk_data->signal_events_sum        = 0;
+	pxtalk_data->xtalk_rate_kcps_per_spad = 0U;
+	pxtalk_data->VL53LX_p_012             = 0U;
+	pxtalk_data->VL53LX_p_013               = 0U;
+	pxtalk_data->target_start             = 0U;
+
+	for (lb = 0; lb < VL53LX_XTALK_HISTO_BINS; lb++)
+		pxtalk_data->bin_data_sums[lb] = 0;
+}
+
+VL53LX_Error VL53LX_wait_for_range_completion(VL53LX_DEV Dev)
+{
+	VL53LX_Error status = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	uint8_t      data_ready  = 0;
+
+	if (pdev->wait_method == VL53LX_WAIT_METHOD_BLOCKING) {
+		status = VL53LX_poll_for_range_completion(Dev, VL53LX_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
+	} else {
+		data_ready = 0;
+		while (data_ready == 0x00 && status == VL53LX_ERROR_NONE) {
+			status = VL53LX_is_new_data_ready(Dev, &data_ready);
+			if (status == VL53LX_ERROR_NONE) {
+				status = 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 = VL53LX_ERROR_NONE;
+
+	pxtalk_data->pll_period_mm = VL53LX_calc_pll_period_mm(phist_bins->VL53LX_p_015);
+	if (pxtalk_data->pll_period_mm == 0)
+		pxtalk_data->pll_period_mm = 1;
+
+	pxtalk_data->xtalk_width_phase = (int32_t)phist_bins->vcsel_width * 128;
+	pxtalk_data->target_width_phase = pxtalk_data->xtalk_width_phase + (int32_t)target_width_oversize * 128;
+
+	pxtalk_data->xtalk_start_phase = (int32_t)phist_bins->zero_distance_phase - (pxtalk_data->xtalk_width_phase / 2);
+	pxtalk_data->xtalk_end_phase  = (int32_t)pxtalk_data->xtalk_start_phase + pxtalk_data->xtalk_width_phase;
+
+	if (pxtalk_data->xtalk_start_phase < 0)
+		pxtalk_data->xtalk_start_phase = 0;
+
+	pxtalk_data->VL53LX_p_012 = (uint8_t)(pxtalk_data->xtalk_start_phase / 2048);
+	pxtalk_data->VL53LX_p_013 = (uint8_t)((pxtalk_data->xtalk_end_phase + 2047) / 2048);
+
+	pxtalk_data->target_start_phase  = (int32_t)target_distance_mm * 2048 * 16;
+	pxtalk_data->target_start_phase += ((int32_t)pxtalk_data->pll_period_mm / 2);
+	pxtalk_data->target_start_phase /= (int32_t)pxtalk_data->pll_period_mm;
+	pxtalk_data->target_start_phase += (int32_t)phist_bins->zero_distance_phase;
+	pxtalk_data->target_start_phase -= (pxtalk_data->target_width_phase / 2);
+	pxtalk_data->target_end_phase  = (int32_t)pxtalk_data->target_start_phase + pxtalk_data->target_width_phase;
+
+	if (pxtalk_data->target_start_phase < 0)
+		pxtalk_data->target_start_phase = 0;
+
+	pxtalk_data->target_start = (uint8_t)(pxtalk_data->target_start_phase / 2048);
+
+	if (pxtalk_data->VL53LX_p_013 > (pxtalk_data->target_start-1))
+		pxtalk_data->VL53LX_p_013 = pxtalk_data->target_start-1;
+
+	pxtalk_data->effective_width = (2048 * ((int32_t)pxtalk_data->VL53LX_p_013+1));
+	pxtalk_data->effective_width -= pxtalk_data->xtalk_start_phase;
+
+	if (pxtalk_data->effective_width > pxtalk_data->xtalk_width_phase)
+		pxtalk_data->effective_width = pxtalk_data->xtalk_width_phase;
+
+	if (pxtalk_data->effective_width < 1)
+		pxtalk_data->effective_width = 1;
+
+	pxtalk_data->event_scaler  =  pxtalk_data->xtalk_width_phase * 1000;
+	pxtalk_data->event_scaler +=  (pxtalk_data->effective_width / 2);
+	pxtalk_data->event_scaler /=  pxtalk_data->effective_width;
+
+	if (pxtalk_data->event_scaler < 1000)
+		pxtalk_data->event_scaler = 1000;
+
+	if (pxtalk_data->event_scaler > 4000)
+		pxtalk_data->event_scaler = 4000;
+
+	pxtalk_data->event_scaler_sum += pxtalk_data->event_scaler;
+
+	pxtalk_data->peak_duration_us_sum += (uint32_t)phist_bins->peak_duration_us;
+
+	pxtalk_data->effective_spad_count_sum += (uint32_t)phist_bins->result__dss_actual_effective_spads;
+
+	pxtalk_data->zero_distance_phase_sum += (uint32_t)phist_bins->zero_distance_phase;
+
+	return status;
+}
+
+VL53LX_Error VL53LX_hist_xtalk_extract_calc_event_sums(VL53LX_histogram_bin_data_t *phist_bins, VL53LX_hist_xtalk_extract_data_t *pxtalk_data)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	uint8_t   lb = 0;
+	uint8_t   i = 0;
+
+	for (lb  = pxtalk_data->VL53LX_p_012; lb <= pxtalk_data->VL53LX_p_013; lb++) {
+		i = (lb + phist_bins->number_of_ambient_bins + phist_bins->VL53LX_p_021) % phist_bins->VL53LX_p_021;
+
+		pxtalk_data->signal_events_sum += phist_bins->bin_data[i];
+		pxtalk_data->signal_events_sum -= phist_bins->VL53LX_p_028;
+	}
+
+	for (lb  = 0; lb < VL53LX_XTALK_HISTO_BINS  && lb < phist_bins->VL53LX_p_021; lb++) {
+		i = (lb + phist_bins->number_of_ambient_bins + phist_bins->VL53LX_p_021) % phist_bins->VL53LX_p_021;
+
+		pxtalk_data->bin_data_sums[lb] += phist_bins->bin_data[i];
+		pxtalk_data->bin_data_sums[lb] -= phist_bins->VL53LX_p_028;
+	}
+
+	pxtalk_data->sample_count += 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 = VL53LX_ERROR_NONE;
+
+	status = VL53LX_hist_xtalk_extract_calc_window(target_distance_mm, target_width_oversize, phist_bins, pxtalk_data);
+
+	if (status == VL53LX_ERROR_NONE) {
+		status = 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_xtalk_extract_data_t *pxtalk_data)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	uint64_t tmp64_0        = 0;
+	uint64_t tmp64_1        = 0;
+	uint64_t xtalk_per_spad = 0;
+
+	tmp64_1 = (uint64_t)pxtalk_data->effective_spad_count_sum * (uint64_t)pxtalk_data->peak_duration_us_sum;
+
+	if (pxtalk_data->signal_events_sum < 0) {
+		pxtalk_data->signal_events_sum = 0;
+
+		tmp64_0 = ((uint64_t)pxtalk_data->sample_count * (uint64_t)pxtalk_data->event_scaler_avg * 256U) << 9U;
+		if (tmp64_0 > 0) {
+			pxtalk_data->signal_events_sum = (int32_t)do_division_u((50U * tmp64_1), tmp64_0);
+		}
+	}
+	tmp64_0 = ((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 = tmp64_0 + (tmp64_1 >> 1U);
+		xtalk_per_spad = do_division_u(tmp64_0, tmp64_1);
+	} else {
+		xtalk_per_spad = (uint64_t)tmp64_0;
+	}
+
+	pxtalk_data->xtalk_rate_kcps_per_spad = (uint32_t)xtalk_per_spad;
+	return status;
+}
+
+VL53LX_Error VL53LX_hist_xtalk_extract_calc_shape(VL53LX_hist_xtalk_extract_data_t *pxtalk_data, VL53LX_xtalk_histogram_shape_t *pxtalk_shape)
+{
+	VL53LX_Error  status = VL53LX_ERROR_NONE;
+
+	int32_t  lb = 0;
+	uint64_t total_events    = 0U;
+	uint64_t tmp64_0         = 0U;
+	int32_t  remaining_area  = 1024;
+
+	pxtalk_shape->VL53LX_p_019 = 0;
+	pxtalk_shape->VL53LX_p_020 = VL53LX_XTALK_HISTO_BINS;
+	pxtalk_shape->VL53LX_p_021 = VL53LX_XTALK_HISTO_BINS;
+
+	pxtalk_shape->zero_distance_phase = (uint16_t)pxtalk_data->zero_distance_phase_avg;
+	pxtalk_shape->phasecal_result__reference_phase = (uint16_t)pxtalk_data->zero_distance_phase_avg + (3*2048);
+
+	if (pxtalk_data->signal_events_sum > 0)
+		total_events = (uint64_t)pxtalk_data->signal_events_sum * (uint64_t)pxtalk_data->event_scaler_avg;
+	else
+		total_events = 1;
+	if (total_events == 0)
+		total_events = 1;
+
+	remaining_area  = 1024;
+	pxtalk_data->max_shape_value = 0;
+
+	for (lb = 0; lb < VL53LX_XTALK_HISTO_BINS; lb++) {
+		if ((lb < (int32_t)pxtalk_data->VL53LX_p_012 || lb > (int32_t)pxtalk_data->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] = (uint32_t)pxtalk_data->max_shape_value;
+					remaining_area -= pxtalk_data->max_shape_value;
+				} else {
+					pxtalk_shape->bin_data[lb] = (uint32_t)remaining_area;
+					remaining_area = 0;
+				}
+			} else {
+				pxtalk_shape->bin_data[lb] = 0;
+			}
+		} else {
+			tmp64_0 = (uint64_t)pxtalk_data->bin_data_sums[lb] * 1024U * 1000U;
+			tmp64_0 += (total_events >> 1);
+			tmp64_0 = do_division_u(tmp64_0, total_events);
+			if (tmp64_0 > 0xFFFFU)
+				tmp64_0 = 0xFFFFU;
+
+			pxtalk_shape->bin_data[lb] = (uint32_t)tmp64_0;
+
+			if ((int32_t)pxtalk_shape->bin_data[lb] > pxtalk_data->max_shape_value)
+				pxtalk_data->max_shape_value = (int32_t)pxtalk_shape->bin_data[lb];
+
+			remaining_area -= (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 = VL53LX_ERROR_NONE;
+	VL53LX_xtalk_calibration_results_t *pX = pxtalk_cal;
+
+	if (pxtalk_data->sample_count > 0) {
+		pxtalk_data->event_scaler_avg  = pxtalk_data->event_scaler_sum;
+		pxtalk_data->event_scaler_avg += (pxtalk_data->sample_count >> 1);
+		pxtalk_data->event_scaler_avg /=  pxtalk_data->sample_count;
+
+		status = VL53LX_hist_xtalk_extract_calc_rate_per_spad(pxtalk_data);
+		if (status == VL53LX_ERROR_NONE) {
+			pxtalk_data->zero_distance_phase_avg  = pxtalk_data->zero_distance_phase_sum;
+			pxtalk_data->zero_distance_phase_avg += (pxtalk_data->sample_count >> 1);
+			pxtalk_data->zero_distance_phase_avg /= pxtalk_data->sample_count;
+			status = VL53LX_hist_xtalk_extract_calc_shape(pxtalk_data, pxtalk_shape);
+
+			pxtalk_shape->phasecal_result__vcsel_start = phist_bins->phasecal_result__vcsel_start;
+			pxtalk_shape->cal_config__vcsel_start = phist_bins->cal_config__vcsel_start;
+			pxtalk_shape->vcsel_width = phist_bins->vcsel_width;
+			pxtalk_shape->VL53LX_p_015 = phist_bins->VL53LX_p_015;
+		}
+
+		if (status == VL53LX_ERROR_NONE) {
+			pX->algo__crosstalk_compensation_plane_offset_kcps = pxtalk_data->xtalk_rate_kcps_per_spad;
+			pX->algo__crosstalk_compensation_x_plane_gradient_kcps = 0U;
+			pX->algo__crosstalk_compensation_y_plane_gradient_kcps = 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 = VL53LX_ERROR_NONE;
+	VL53LX_LLDriverData_t *pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	VL53LX_xtalkextract_config_t *pX = &(pdev->xtalk_extract_cfg);
+	VL53LX_xtalk_config_t *pC = &(pdev->xtalk_cfg);
+	VL53LX_xtalk_calibration_results_t *pXC = &(pdev->xtalk_cal);
+
+	uint8_t smudge_corr_en   = 0;
+	uint8_t i                = 0;
+	int8_t k = 0;
+	uint8_t nbloops;
+	int32_t initMergeSize = 0;
+	int32_t MergeEnabled = 0;
+	uint32_t deltaXtalk;
+	uint32_t stepXtalk;
+	uint32_t XtalkMin;
+	uint32_t XtalkMax;
+	uint8_t measurement_mode = VL53LX_DEVICEMEASUREMENTMODE_BACKTOBACK;
+	int8_t MaxId;
+	uint8_t histo_merge_nb;
+	uint8_t wait_for_accumulation;
+	VL53LX_range_results_t *prange_results = (VL53LX_range_results_t *) pdev->wArea1;
+	uint8_t Very1stRange = 0;
+
+	if (status == VL53LX_ERROR_NONE)
+		status =
+			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 == VL53LX_ERROR_NONE)
+		status = VL53LX_disable_xtalk_compensation(Dev);
+
+	smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_dynamic_xtalk_correction_disable(Dev);
+
+	VL53LX_load_patch(Dev);
+
+	VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, &initMergeSize);
+	VL53LX_get_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE, &MergeEnabled);
+	memset(&pdev->xtalk_cal, 0,	sizeof(pdev->xtalk_cal));
+
+	if (status == VL53LX_ERROR_NONE)
+		status = VL53LX_init_and_start_range(Dev, measurement_mode, VL53LX_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
+
+	MaxId = pdev->tuning_parms.tp_hist_merge_max_size - 1;
+	nbloops = (MergeEnabled == 0 ? 1 : 2);
+	for (k = 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 * MaxId + 1);
+
+		for (i = 0; i <= pX->num_of_samples; i++) {
+			if (status == VL53LX_ERROR_NONE)
+				status = VL53LX_wait_for_range_completion(Dev);
+			if (status == VL53LX_ERROR_NONE)
+				status = VL53LX_get_device_results(Dev, VL53LX_DEVICERESULTSLEVEL_FULL, prange_results);
+			Very1stRange = (pdev->ll_state.rd_device_state == VL53LX_DEVICESTATE_RANGING_WAIT_GPH_SYNC);
+
+			VL53LX_compute_histo_merge_nb(Dev, &histo_merge_nb);
+			wait_for_accumulation = ((k != 0) && (MergeEnabled) && (status == VL53LX_ERROR_NONE) && (histo_merge_nb < pdev->tuning_parms.tp_hist_merge_max_size));
+			if (wait_for_accumulation)
+				i = 0;
+			else {
+				if ((status == VL53LX_ERROR_NONE) && (!Very1stRange)) {
+					status = VL53LX_hist_xtalk_extract_update(cal_distance_mm, OVERSIZE, &(pdev->hist_data), &(pdev->xtalk_extract));
+				}
+			}
+			if (status == VL53LX_ERROR_NONE)
+				status = VL53LX_clear_interrupt_and_enable_next_range(Dev, measurement_mode);
+		}
+		if (status == VL53LX_ERROR_NONE)
+			status = VL53LX_hist_xtalk_extract_fini(&(pdev->hist_data), &(pdev->xtalk_extract), &(pdev->xtalk_cal), &(pdev->xtalk_shapes.xtalk_shape));
+
+		if (status == VL53LX_ERROR_NONE) {
+			pXC->algo__xtalk_cpo_HistoMerge_kcps[k * MaxId] = pXC->algo__crosstalk_compensation_plane_offset_kcps;
+		}
+	}
+	VL53LX_stop_range(Dev);
+
+	VL53LX_set_tuning_parm(Dev, VL53LX_TUNINGPARM_HIST_MERGE_MAX_SIZE, initMergeSize);
+	VL53LX_unload_patch(Dev);
+
+	if (status != VL53LX_ERROR_NONE)
+		status = VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
+	else if ((MergeEnabled == 1) && (MaxId > 0)) {
+		XtalkMin = pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[0];
+		XtalkMax = pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[MaxId];
+		pdev->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps = XtalkMin;
+		if (XtalkMax > XtalkMin) {
+			deltaXtalk =  XtalkMax - XtalkMin;
+			stepXtalk = deltaXtalk / MaxId;
+			for (k = 1; k < MaxId; k++)
+			pdev->xtalk_cal.algo__xtalk_cpo_HistoMerge_kcps[k] = XtalkMin + stepXtalk * k;
+		} else
+			status = VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL;
+	}
+	if (status == VL53LX_ERROR_NONE) {
+		pC->algo__crosstalk_compensation_x_plane_gradient_kcps = pXC->algo__crosstalk_compensation_x_plane_gradient_kcps;
+		pC->algo__crosstalk_compensation_y_plane_gradient_kcps = pXC->algo__crosstalk_compensation_y_plane_gradient_kcps;
+		pC->algo__crosstalk_compensation_plane_offset_kcps = pXC->algo__crosstalk_compensation_plane_offset_kcps;
+	}
+	pdev->xtalk_results.cal_status = status;
+	*pcal_status = pdev->xtalk_results.cal_status;
+
+	status = VL53LX_enable_xtalk_compensation(Dev);
+	if (smudge_corr_en == 1)
+		status = VL53LX_dynamic_xtalk_correction_enable(Dev);
+
+	return status;
+}
+
+VL53LX_Error VL53LX_PerformXTalkCalibration(VL53LX_DEV Dev)
+{
+	VL53LX_Error Status = 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 = BDTable[VL53LX_TUNING_XTALK_FULL_ROI_BIN_SUM_MARGIN];
+	uint32_t DefaultOffset = BDTable[VL53LX_TUNING_XTALK_FULL_ROI_DEFAULT_OFFSET];
+	uint32_t *pLLDataPlaneOffsetKcps;
+	uint32_t sum = 0;
+	uint8_t binok = 0;
+
+	pPlaneOffsetKcps = &caldata.customer.algo__crosstalk_compensation_plane_offset_kcps;
+	pLLData = VL53LXDevStructGetLLDriverHandle(Dev);
+	pLLDataPlaneOffsetKcps = &pLLData->xtalk_cal.algo__crosstalk_compensation_plane_offset_kcps;
+
+	CalDistanceMm = (int16_t)
+	BDTable[VL53LX_TUNING_XTALK_FULL_ROI_TARGET_DISTANCE_MM];
+	Status = VL53LX_run_hist_xtalk_extraction(Dev, CalDistanceMm, &UStatus);
+
+	VL53LX_GetCalibrationData(Dev, &caldata);
+	for (i = 0; i < VL53LX_XTALK_HISTO_BINS; i++) {
+		sum += caldata.xtalkhisto.xtalk_shape.bin_data[i];
+		if (caldata.xtalkhisto.xtalk_shape.bin_data[i] > 0)
+			binok++;
+	}
+	if ((UStatus == VL53LX_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL) || (sum > (1024 + Margin)) || (sum < (1024 - Margin)) || (binok < 3)) {
+		*pPlaneOffsetKcps = DefaultOffset;
+		*pLLDataPlaneOffsetKcps = DefaultOffset;
+		caldata.xtalkhisto.xtalk_shape.bin_data[0] = 307;
+		caldata.xtalkhisto.xtalk_shape.bin_data[1] = 410;
+		caldata.xtalkhisto.xtalk_shape.bin_data[2] = 410;
+		caldata.xtalkhisto.xtalk_shape.bin_data[3] = 307;
+		for (i = 4; i < VL53LX_XTALK_HISTO_BINS; i++)
+			caldata.xtalkhisto.xtalk_shape.bin_data[i] = 0;
+		for (i = 0; i < VL53LX_BIN_REC_SIZE; i++)
+			caldata.algo__xtalk_cpo_HistoMerge_kcps[i] = DefaultOffset + DefaultOffset * i;
+		VL53LX_SetCalibrationData(Dev, &caldata);
+	}
+
+	if (Status == VL53LX_ERROR_NONE) {
+		Status = VL53LX_get_current_xtalk_settings(Dev, &xtalk);
+		Status = VL53LX_set_tuning_parm(Dev, VL53LX_TUNINGPARM_DYNXTALK_NODETECT_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 = 0;
+
+	rc = stmvl53lx_sendparams(data);
+	if (rc)
+		goto done;
+
+	rc = VL53LX_PerformXTalkCalibration(&data->stdev);
+	if (rc) {
+		vl53lx_errmsg("VL53LX_PerformXTalkCalibration fail => %d", rc);
+		rc = store_last_error(data, rc);
+	}
+
+	data->crosstalk_enable = 1;
+done:
+		return rc;
+}
+
+VL53LX_Error VL53LX_PerformOffsetSimpleCalibration(VL53LX_DEV Dev, int32_t CalDistanceMilliMeter)
+{
+	VL53LX_Error Status = 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 = VL53LX_ERROR_NONE;
+	uint8_t smudge_corr_en;
+	VL53LX_TargetRangeData_t *pRange;
+
+	pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
+	SmudgeStatus = VL53LX_dynamic_xtalk_correction_disable(Dev);
+
+	pdev->customer.algo__part_to_part_range_offset_mm = 0;
+	pdev->customer.mm_config__inner_offset_mm = 0;
+	pdev->customer.mm_config__outer_offset_mm = 0;
+	memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
+	Repeat = BDTable[VL53LX_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT];
+	Max = BDTable[VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
+	UnderMax = 1 + (Max / 2);
+	OverMax = Max + (Max / 2);
+	sum_ranging = 0;
+	total_count = 0;
+
+	while ((Repeat > 0) && (Status == VL53LX_ERROR_NONE)) {
+		Status = VL53LX_StartMeasurement(Dev);
+		if (Status == VL53LX_ERROR_NONE) {
+			VL53LX_WaitMeasurementDataReady(Dev);
+			VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData);
+			VL53LX_ClearInterruptAndStartMeasurement(Dev);
+		}
+		inloopcount = 0;
+		offset_meas = 0;
+		while ((Status == VL53LX_ERROR_NONE) && (inloopcount < Max) && (offset_meas < OverMax)) {
+			Status = VL53LX_WaitMeasurementDataReady(Dev);
+			if (Status == VL53LX_ERROR_NONE)
+				Status = VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData);
+			pRange = &(RangingMeasurementData.RangeData[0]);
+			goodmeas = (pRange->RangeStatus == VL53LX_RANGESTATUS_RANGE_VALID);
+			if ((Status == VL53LX_ERROR_NONE) && goodmeas) {
+				sum_ranging += pRange->RangeMilliMeter;
+				inloopcount++;
+			}
+			Status = VL53LX_ClearInterruptAndStartMeasurement(Dev);
+			offset_meas++;
+		}
+		total_count += inloopcount;
+		if (inloopcount < UnderMax)
+			Status = VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
+
+		VL53LX_StopMeasurement(Dev);
+		Repeat--;
+	}
+	if ((SmudgeStatus == VL53LX_ERROR_NONE) && (smudge_corr_en == 1))
+		SmudgeStatus = VL53LX_dynamic_xtalk_correction_enable(Dev);
+
+	if ((sum_ranging < 0) || (sum_ranging > ((int32_t) total_count * 0xffff)))
+		Status = VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
+
+	if ((Status == VL53LX_ERROR_NONE) && (total_count > 0)) {
+		IncRounding = total_count / 2;
+		meanDistance_mm = (int16_t)((sum_ranging + IncRounding) / total_count);
+		offset = (int16_t)CalDistanceMilliMeter - meanDistance_mm;
+		pdev->customer.algo__part_to_part_range_offset_mm = 0;
+		pdev->customer.mm_config__inner_offset_mm = offset;
+		pdev->customer.mm_config__outer_offset_mm = offset;
+
+		Status = VL53LX_set_customer_nvm_managed(Dev, &(pdev->customer));
+	}
+	return Status;
+}
+
+static int ctrl_perform_simple_calibration_offset_lock(struct stmvl53lx_data *data, struct stmvl53lx_ioctl_perform_calibration_t *calib)
+{
+	int rc = 0;
+
+	data->is_delay_allowed = 1;
+	rc = stmvl53lx_sendparams(data);
+	if (rc)
+		goto done;
+
+	rc = VL53LX_PerformOffsetSimpleCalibration(&data->stdev, calib->param1);
+	data->is_delay_allowed = 0;
+	if (rc) {
+		vl53lx_errmsg(
+			"VL53LX_PerformOffsetSimpleCalibration fail => %d", rc);
+		rc = store_last_error(data, rc);
+	}
+
+done:
+	return rc;
+}
+
+VL53LX_Error VL53LX_GetDistanceMode(VL53LX_DEV Dev, VL53LX_DistanceModes *pDistanceMode)
+{
+	VL53LX_Error Status = VL53LX_ERROR_NONE;
+
+	*pDistanceMode = VL53LXDevDataGet(Dev, CurrentParameters.DistanceMode);
+
+	return Status;
+}
+
+VL53LX_Error VL53LX_PerformOffsetPerVcselCalibration(VL53LX_DEV Dev, int32_t CalDistanceMilliMeter)
+{
+	VL53LX_Error Status = 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] = {VL53LX_DISTANCEMODE_SHORT, VL53LX_DISTANCEMODE_MEDIUM, VL53LX_DISTANCEMODE_LONG};
+	int16_t offsetA[3] = {0, 0, 0};
+	int16_t offsetB[3] = {0, 0, 0};
+
+	VL53LX_Error SmudgeStatus = VL53LX_ERROR_NONE;
+	uint8_t smudge_corr_en, ics;
+	VL53LX_TargetRangeData_t *pRange;
+
+	pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+
+	smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
+	SmudgeStatus = VL53LX_dynamic_xtalk_correction_disable(Dev);
+
+	pdev->customer.algo__part_to_part_range_offset_mm = 0;
+	pdev->customer.mm_config__inner_offset_mm = 0;
+	pdev->customer.mm_config__outer_offset_mm = 0;
+	pdev->customer.mm_config__outer_offset_mm = 0;
+	memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
+
+	Repeat = 0;
+	if (IsL4(Dev))
+		Repeat = 1;
+	Max = 2 * BDTable[VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
+	UnderMax = 1 + (Max / 2);
+	OverMax = Max + (Max / 2);
+
+	Status = VL53LX_GetDistanceMode(Dev, &currentDist);
+
+	while ((Repeat < 3) && (Status == VL53LX_ERROR_NONE)) {
+		Status = VL53LX_SetDistanceMode(Dev, DistMode[Repeat]);
+		Status = VL53LX_StartMeasurement(Dev);
+
+		if (Status == VL53LX_ERROR_NONE) {
+			VL53LX_WaitMeasurementDataReady(Dev);
+			VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData);
+			VL53LX_ClearInterruptAndStartMeasurement(Dev);
+		}
+		inloopcount = 0;
+		offset_meas_range_A = 0;
+		sum_ranging_range_A = 0;
+		offset_meas_range_B = 0;
+		sum_ranging_range_B = 0;
+		while ((Status == VL53LX_ERROR_NONE) && (inloopcount < Max) && (inloopcount < OverMax)) {
+			Status = VL53LX_WaitMeasurementDataReady(Dev);
+			if (Status == VL53LX_ERROR_NONE)
+				Status = VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData);
+			pRange = &(RangingMeasurementData.RangeData[0]);
+			goodmeas = (pRange->RangeStatus == VL53LX_RANGESTATUS_RANGE_VALID);
+			ics = pdev->ll_state.cfg_internal_stream_count;
+			if ((Status == VL53LX_ERROR_NONE) && goodmeas) {
+				if (ics & 0x01) {
+					sum_ranging_range_A += pRange->RangeMilliMeter;
+					offset_meas_range_A++;
+				} else {
+					sum_ranging_range_B += pRange->RangeMilliMeter;
+					offset_meas_range_B++;
+				}
+				inloopcount = offset_meas_range_A + offset_meas_range_B;
+			}
+			Status = VL53LX_ClearInterruptAndStartMeasurement(Dev);
+		}
+		if (inloopcount < UnderMax)
+			Status = 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 = VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
+		}
+
+		if ((Status == VL53LX_ERROR_NONE) && (offset_meas_range_A > 0)) {
+			IncRounding = offset_meas_range_A / 2;
+			meanDistance_mm = (int16_t)((sum_ranging_range_A + IncRounding) / offset_meas_range_A);
+			offsetA[Repeat] = (int16_t)CalDistanceMilliMeter - meanDistance_mm;
+		}
+
+		if ((Status == VL53LX_ERROR_NONE) && (offset_meas_range_B > 0)) {
+			IncRounding = offset_meas_range_B / 2;
+			meanDistance_mm = (int16_t)((sum_ranging_range_B + IncRounding) / offset_meas_range_B);
+			offsetB[Repeat] = (int16_t)CalDistanceMilliMeter - meanDistance_mm;
+		}
+		Repeat++;
+	}
+
+	if ((SmudgeStatus == VL53LX_ERROR_NONE) && (smudge_corr_en == 1))
+		SmudgeStatus = VL53LX_dynamic_xtalk_correction_enable(Dev);
+
+	if (Status == VL53LX_ERROR_NONE) {
+		pdev->per_vcsel_cal_data.short_a_offset_mm  = offsetA[0];
+		pdev->per_vcsel_cal_data.short_b_offset_mm  = offsetB[0];
+		pdev->per_vcsel_cal_data.medium_a_offset_mm = offsetA[1];
+		pdev->per_vcsel_cal_data.medium_b_offset_mm = offsetB[1];
+		pdev->per_vcsel_cal_data.long_a_offset_mm   = offsetA[2];
+		pdev->per_vcsel_cal_data.long_b_offset_mm   = 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 = 0;
+
+	data->is_delay_allowed = 1;
+
+	rc = stmvl53lx_sendparams(data);
+	if (rc)
+		goto done;
+
+	rc = VL53LX_PerformOffsetPerVcselCalibration(&data->stdev, calib->param1);
+	data->is_delay_allowed = 0;
+	if (rc) {
+		vl53lx_errmsg(
+		"VL53LX_PerformOffsetPerVcselCalibration fail => %d", rc);
+		rc = store_last_error(data, rc);
+	}
+
+done:
+	return rc;
+}
+
+VL53LX_Error VL53LX_PerformOffsetZeroDistanceCalibration(VL53LX_DEV Dev)
+{
+	#define START_OFFSET 50
+	VL53LX_Error Status = 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 = VL53LX_ERROR_NONE;
+	uint8_t smudge_corr_en;
+	VL53LX_TargetRangeData_t *pRange;
+
+	pdev = VL53LXDevStructGetLLDriverHandle(Dev);
+	smudge_corr_en = pdev->smudge_correct_config.smudge_corr_enabled;
+	SmudgeStatus = VL53LX_dynamic_xtalk_correction_disable(Dev);
+	pdev->customer.algo__part_to_part_range_offset_mm = 0;
+	pdev->customer.mm_config__inner_offset_mm = START_OFFSET;
+	pdev->customer.mm_config__outer_offset_mm = START_OFFSET;
+	memset(&pdev->per_vcsel_cal_data, 0, sizeof(pdev->per_vcsel_cal_data));
+	ZeroDistanceOffset = BDTable[VL53LX_TUNING_ZERO_DISTANCE_OFFSET_NON_LINEAR_FACTOR];
+	Repeat = BDTable[VL53LX_TUNING_SIMPLE_OFFSET_CALIBRATION_REPEAT];
+	Max = BDTable[VL53LX_TUNING_MAX_SIMPLE_OFFSET_CALIBRATION_SAMPLE_NUMBER];
+	UnderMax = 1 + (Max / 2);
+	OverMax = Max + (Max / 2);
+	sum_ranging = 0;
+	total_count = 0;
+
+	while ((Repeat > 0) && (Status == VL53LX_ERROR_NONE)) {
+		Status = VL53LX_StartMeasurement(Dev);
+		if (Status == VL53LX_ERROR_NONE) {
+			VL53LX_WaitMeasurementDataReady(Dev);
+			VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData);
+			VL53LX_ClearInterruptAndStartMeasurement(Dev);
+		}
+		inloopcount = 0;
+		offset_meas = 0;
+		while ((Status == VL53LX_ERROR_NONE) && (inloopcount < Max) && (offset_meas < OverMax)) {
+			Status = VL53LX_WaitMeasurementDataReady(Dev);
+			if (Status == VL53LX_ERROR_NONE)
+				Status = VL53LX_GetMultiRangingData(Dev, &RangingMeasurementData);
+			pRange = &(RangingMeasurementData.RangeData[0]);
+			goodmeas = (pRange->RangeStatus == VL53LX_RANGESTATUS_RANGE_VALID);
+			if ((Status == VL53LX_ERROR_NONE) && goodmeas) {
+				sum_ranging = sum_ranging + pRange->RangeMilliMeter;
+				inloopcount++;
+			}
+			Status = VL53LX_ClearInterruptAndStartMeasurement(Dev);
+			offset_meas++;
+		}
+		total_count += inloopcount;
+		if (inloopcount < UnderMax)
+			Status = VL53LX_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
+		VL53LX_StopMeasurement(Dev);
+		Repeat--;
+	}
+	if ((SmudgeStatus == VL53LX_ERROR_NONE) && (smudge_corr_en == 1))
+		SmudgeStatus = VL53LX_dynamic_xtalk_correction_enable(Dev);
+	if ((sum_ranging < 0) || (sum_ranging > ((int32_t) total_count * 0xffff)))
+		Status = VL53LX_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
+
+	if ((Status == VL53LX_ERROR_NONE) && (total_count > 0)) {
+		IncRounding = total_count / 2;
+		meanDistance_mm = (int16_t)((sum_ranging + IncRounding) / total_count);
+		offset = START_OFFSET - meanDistance_mm + ZeroDistanceOffset;
+		pdev->customer.algo__part_to_part_range_offset_mm = 0;
+		pdev->customer.mm_config__inner_offset_mm = offset;
+		pdev->customer.mm_config__outer_offset_mm = offset;
+		Status = VL53LX_set_customer_nvm_managed(Dev, &(pdev->customer));
+	}
+
+	return Status;
+}
+
+static int ctrl_perform_zero_distance_calibration_offset_lock(struct stmvl53lx_data *data, struct stmvl53lx_ioctl_perform_calibration_t *calib)
+{
+	int rc = 0;
+
+	data->is_delay_allowed = 1;
+
+	rc = stmvl53lx_sendparams(data);
+	if (rc)
+		goto done;
+
+	rc = VL53LX_PerformOffsetZeroDistanceCalibration(&data->stdev);
+	data->is_delay_allowed = 0;
+	if (rc) {
+		vl53lx_errmsg(
+		"VL53LX_PerformOffsetZeroDistanceCalibration fail => %d", rc);
+		rc = store_last_error(data, rc);
+	}
+
+done:
+	return rc;
+}
+
+static int ctrl_perform_calibration(struct stmvl53lx_data *data, void __user *p)
+{
+	int rc = 0;
+	struct stmvl53lx_ioctl_perform_calibration_t calib;
+
+	mutex_lock(&data->work_mutex);
+
+	if (data->is_device_remove) {
+		rc = -ENODEV;
+		goto done;
+	}
+	data->is_calibrating = true;
+	rc = copy_from_user(&calib, p, sizeof(calib));
+	if (rc) {
+		rc = -EFAULT;
+		goto done;
+	}
+	if (data->enable_sensor) {
+		rc = -EBUSY;
+		vl53lx_errmsg("can't perform calibration while ranging\n");
+		goto done;
+	}
+
+	rc = reset_release(data);
+	if (rc)
+		goto done;
+
+	switch (calib.calibration_type) {
+	case VL53LX_CALIBRATION_REF_SPAD:
+		rc = ctrl_perform_calibration_ref_spad_lock(data, &calib);
+		break;
+	case VL53LX_CALIBRATION_CROSSTALK:
+		rc = ctrl_perform_calibration_crosstalk_lock(data, &calib);
+		break;
+	case VL53LX_CALIBRATION_OFFSET:
+		rc = ctrl_perform_simple_calibration_offset_lock(data, &calib);
+		break;
+	case VL53LX_CALIBRATION_OFFSET_SIMPLE:
+		rc = ctrl_perform_simple_calibration_offset_lock(data, &calib);
+		break;
+	case VL53LX_CALIBRATION_OFFSET_PER_VCSEL:
+		rc = ctrl_perform_per_vcsel_calibration_offset_lock(data, &calib);
+		break;
+	case VL53LX_CALIBRATION_OFFSET_ZERO_DISTANCE:
+		rc = ctrl_perform_zero_distance_calibration_offset_lock(data,
+			&calib);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	reset_hold(data);
+
+done:
+	data->is_calibrating = false;
+	data->is_first_start_done = true;
+	mutex_unlock(&data->work_mutex);
+
+	return rc;
+}
+
+static int ctrl_mz_data_additional(struct stmvl53lx_data *data, void __user *p)
+{
+	return ctrl_mz_data_common(data, p, true);
+}
+
+static int ctrl_mz_data_blocking_additional(struct stmvl53lx_data *data, void __user *p)
+{
+	return ctrl_mz_data_blocking_common(data, p, true);
+}
+
+static int stmvl53lx_ioctl_handler(struct stmvl53lx_data *data, unsigned int cmd, unsigned long arg, void __user *p)
+{
+	int rc = 0;
+
+	if (!data)
+		return -EINVAL;
+
+	switch (cmd) {
+	case VL53LX_IOCTL_START:
+		vl53lx_dbgmsg("VL53LX_IOCTL_START\n");
+		rc = ctrl_start(data);
+		break;
+	case VL53LX_IOCTL_STOP:
+		vl53lx_dbgmsg("VL53LX_IOCTL_STOP\n");
+		rc = ctrl_stop(data);
+		break;
+	case VL53LX_IOCTL_REGISTER:
+		vl53lx_dbgmsg("VL53LX_IOCTL_REGISTER\n");
+		rc = ctrl_reg_access(data, p);
+		break;
+	case VL53LX_IOCTL_PARAMETER:
+		vl53lx_dbgmsg("VL53LX_IOCTL_PARAMETER\n");
+		rc = ctrl_params(data, p);
+		break;
+	case VL53LX_IOCTL_ROI:
+		vl53lx_dbgmsg("VL53LX_IOCTL_ROI\n");
+		rc = ctrl_roi(data, p);
+		break;
+	case VL53LX_IOCTL_MZ_DATA:
+		rc = ctrl_mz_data(data, p);
+		break;
+	case VL53LX_IOCTL_MZ_DATA_BLOCKING:
+		rc = ctrl_mz_data_blocking(data, p);
+		break;
+	case VL53LX_IOCTL_CALIBRATION_DATA:
+		vl53lx_dbgmsg("VL53LX_IOCTL_CALIBRATION_DATA\n");
+		rc = ctrl_calibration_data(data, p);
+		break;
+	case VL53LX_IOCTL_PERFORM_CALIBRATION:
+		vl53lx_dbgmsg("VL53LX_IOCTL_PERFORM_CALIBRATION\n");
+		rc = ctrl_perform_calibration(data, p);
+		break;
+	case VL53LX_IOCTL_MZ_DATA_ADDITIONAL:
+		rc = ctrl_mz_data_additional(data, p);
+		break;
+	case VL53LX_IOCTL_MZ_DATA_ADDITIONAL_BLOCKING:
+		rc = ctrl_mz_data_blocking_additional(data, p);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
+static long stmvl53lx_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long ret;
+	struct stmvl53lx_data *data = container_of(file->private_data, struct stmvl53lx_data, miscdev);
+	ret = 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 = container_of(file->private_data, struct stmvl53lx_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 = container_of(file->private_data, struct stmvl53lx_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 = {
+	.owner =		THIS_MODULE,
+	.unlocked_ioctl =	stmvl53lx_ioctl,
+	.open =			stmvl53lx_open,
+	.release =		stmvl53lx_release,
+};
+
+int stmvl53lx_setup(struct stmvl53lx_data *data)
+{
+	int rc = 0;
+	VL53LX_DeviceInfo_t dev_info;
+
+	vl53lx_dbgmsg("Enter\n");
+
+	data->id = 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] = data;
+
+	mutex_init(&data->work_mutex);
+
+	INIT_DELAYED_WORK(&data->dwork, stmvl53lx_work_handler);
+	data->force_device_on_en = force_device_on_en_default;
+	data->reset_state = 1;
+	data->is_calibrating = false;
+	data->last_error = VL53LX_ERROR_NONE;
+	data->is_device_remove = false;
+
+	rc = 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 = reset_release(data);
+	if (rc)
+		goto exit_func_end;
+
+	rc = 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 = false;
+
+	rc = sysfs_create_group(&data->input_dev_ps->dev.kobj, &stmvl53lx_attr_group);
+	if (rc) {
+		rc = -ENOMEM;
+		vl53lx_errmsg("%d error:%d\n", __LINE__, rc);
+		goto exit_unregister_dev_ps;
+	}
+	rc = sysfs_create_bin_file(&data->input_dev_ps->dev.kobj,
+		&stmvl53lx_calib_data_attr);
+	if (rc) {
+		rc = -ENOMEM;
+		vl53lx_errmsg("%d error:%d\n", __LINE__, rc);
+		goto exit_unregister_dev_ps;
+	}
+	data->enable_sensor = 0;
+	data->poll_delay_ms = STMVL53LX_CFG_POLL_DELAY_MS;
+	data->timing_budget = STMVL53LX_CFG_TIMING_BUDGET_US;
+	data->distance_mode = STMVL53LX_CFG_DEFAULT_DISTANCE_MODE;
+	data->crosstalk_enable = STMVL53LX_CFG_DEFAULT_CROSSTALK_ENABLE;
+	data->offset_correction_mode = STMVL53LX_CFG_DEFAULT_OFFSET_CORRECTION_MODE;
+	data->smudge_correction_mode = STMVL53LX_CFG_DEFAULT_SMUDGE_CORRECTION_MODE;
+	data->is_xtalk_value_changed = false;
+	data->is_delay_allowed = true;
+
+	rc = VL53LX_DataInit(&data->stdev);
+	data->is_delay_allowed = false;
+	if (rc) {
+		vl53lx_errmsg("VL53LX_DataInit %d\n", rc);
+		goto exit_unregister_dev_ps;
+	}
+
+	rc = VL53LX_GetUserROI(&data->stdev, &(data->roi_cfg));
+	if (rc) {
+		vl53lx_errmsg("VL53LX_GetUserROI %d\n", rc);
+		goto exit_unregister_dev_ps;
+	}
+
+	rc = 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 = VL53LX_GetOpticalCenter(&data->stdev, &data->optical_offset_x, &data->optical_offset_y);
+	if (rc) {
+		vl53lx_errmsg("VL53LX_GetOpticalCenter %d\n", rc);
+		goto exit_unregister_dev_ps;
+	}
+
+	rc = setup_tunings(data);
+	if (rc) {
+		vl53lx_errmsg("setup_tunings %d\n", rc);
+		goto exit_unregister_dev_ps;
+	}
+
+	data->poll_mode = 0;
+	rc = stmvl53lx_module_func_tbl.start_intr(data->client_object, &data->poll_mode);
+	if (rc < 0) {
+		vl53lx_errmsg("can't start no  intr\n");
+		goto exit_unregister_dev_ps;
+	}
+
+	data->is_first_irq = true;
+	data->is_first_start_done = false;
+	data->is_delay_allowed = false;
+
+	data->miscdev.minor = MISC_DYNAMIC_MINOR;
+	if (data->id == 0)
+		strcpy(data->name, VL53LX_MISC_DEV_NAME);
+	else
+		sprintf(data->name, "%s%d", VL53LX_MISC_DEV_NAME, data->id);
+
+	data->miscdev.name = data->name;
+	data->miscdev.fops = &stmvl53lx_ranging_fops;
+	vl53lx_errmsg("Misc device registration name:%s\n", data->miscdev.name);
+	rc = misc_register(&data->miscdev);
+	if (rc != 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_data)
+{
+	struct i2c_client *client = (struct i2c_client *) i2c_data->client;
+	int rc = 0;
+	u32 reg;
+
+	i2c_data->vdd = NULL;
+	i2c_data->pwren_gpio = -1;
+	i2c_data->xsdn_gpio = -1;
+	i2c_data->intr_gpio = -1;
+	i2c_data->boot_reg = STMVL53LX_SLAVE_ADDR;
+	if (force_device) {
+		i2c_data->xsdn_gpio = xsdn_gpio_nb;
+		i2c_data->pwren_gpio = pwren_gpio_nb;
+		i2c_data->intr_gpio = intr_gpio_nb;
+		client->addr = i2c_addr_nb;
+	} else if (dev->of_node) {
+		i2c_data->vdd = devm_regulator_get_optional(dev, "vdd");
+		if (IS_ERR(i2c_data->vdd) || i2c_data->vdd == NULL) {
+			i2c_data->vdd = NULL;
+			i2c_data->pwren_gpio = of_get_named_gpio(dev->of_node, "pwren-gpio", 0);
+			if (i2c_data->pwren_gpio < 0) {
+				i2c_data->pwren_gpio = -1;
+				vl53lx_wanrmsg("no regulator, nor power gpio => power ctrl disabled");
+			}
+		}
+
+		rc = of_property_read_u32_array(dev->of_node, "reg", &reg, 1);
+		if (rc) {
+			vl53lx_wanrmsg("Unable to find reg %d 0x%x", rc, i2c_addr_nb);
+			reg = i2c_addr_nb;
+		}
+		client->addr = reg;
+
+		i2c_data->xsdn_gpio = 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_gpio);
+			i2c_data->xsdn_gpio = -1;
+		}
+
+		i2c_data->intr_gpio = 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_gpio);
+			i2c_data->intr_gpio = -1;
+		}
+
+		rc = of_property_read_u32_array(dev->of_node, "boot-reg", &i2c_data->boot_reg, 1);
+		if (rc) {
+			vl53lx_wanrmsg("Unable to find boot-reg %d %d", rc, i2c_data->boot_reg);
+			i2c_data->boot_reg = STMVL53LX_SLAVE_ADDR;
+		}
+	}
+
+	rc = get_xsdn(dev, i2c_data);
+	if (rc)
+		goto no_xsdn;
+	rc = get_pwren(dev, i2c_data);
+	if (rc)
+		goto no_pwren;
+	rc = 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 = 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 = NULL;
+	}
+	put_pwren(i2c_data);
+	put_intr(i2c_data);
+}
+
+void stmvl53lx_cleanup(struct stmvl53lx_data *data)
+{
+	int rc = 0;
+
+	vl53lx_dbgmsg("enter\n");
+	rc = _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 != NULL) {
+		vl53lx_dbgmsg("to unregister misc dev\n");
+		misc_deregister(&data->miscdev);
+	}
+
+	data->force_device_on_en = 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 = true;
+}
+
+static int stmvl53lx_probe(struct i2c_client *client)
+{
+	int rc = 0;
+	struct stmvl53lx_data *vl53lx_data = NULL;
+	struct i2c_data *i2c_data = NULL;
+
+	vl53lx_dbgmsg("Enter %s : 0x%02x\n", client->name, client->addr);
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
+		rc = -EIO;
+		return rc;
+	}
+
+	vl53lx_data = kzalloc(sizeof(struct stmvl53lx_data), GFP_KERNEL);
+	if (!vl53lx_data) {
+		rc = -ENOMEM;
+		return rc;
+	}
+	if (vl53lx_data) {
+		vl53lx_data->client_object = kzalloc(sizeof(struct i2c_data), GFP_KERNEL);
+		if (!vl53lx_data)
+			goto done_freemem;
+		i2c_data = (struct i2c_data *)vl53lx_data->client_object;
+	}
+
+	i2c_data->client = client;
+	i2c_data->vl53lx_data = vl53lx_data;
+	i2c_data->irq = -1;
+
+	rc = stmvl53lx_parse_tree(&i2c_data->client->dev, i2c_data);
+	if (rc)
+		goto done_freemem;
+
+	i2c_set_clientdata(client, vl53lx_data);
+
+	rc = 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 = i2c_get_clientdata(client);
+	struct i2c_data *i2c_data = (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 = 0;
+
+	vl53lx_dbgmsg("Enter\n");
+
+	rc = _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 = 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 = 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_resume);
+
+static const struct i2c_device_id stmvl53lx_id[] = {
+	{ STMVL53LX_DRV_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, stmvl53lx_id);
+
+static const struct of_device_id st_stmvl53lx_dt_match[] = {
+	{ .compatible = "st,vl53l4cx", },
+	{ },
+};
+
+static struct i2c_driver stmvl53lx_driver = {
+	.driver = {
+		.name	= STMVL53LX_DRV_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = st_stmvl53lx_dt_match,
+		.pm	= &stmvl53lx_pm_ops,
+	},
+	.probe	= stmvl53lx_probe,
+	.remove	= stmvl53lx_remove,
+	.id_table = stmvl53lx_id,
+
+};
+
+static int insert_device(void)
+{
+	int ret = 0;
+	struct i2c_adapter *adapter;
+	struct i2c_board_info info = {
+		.type = "stmvl53lx",
+		.addr = STMVL53LX_SLAVE_ADDR,
+	};
+
+	memset(&info, 0, sizeof(info));
+	strcpy(info.type, "stmvl53lx");
+	info.addr = STMVL53LX_SLAVE_ADDR;
+	adapter = i2c_get_adapter(adapter_nb);
+	if (!adapter) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	stm_test_i2c_client = i2c_new_client_device(adapter, &info);
+	if (!stm_test_i2c_client)
+		ret = -EINVAL;
+
+done:
+	return ret;
+}
+
+static int __init stmvl53lx_init(void)
+{
+	int rc = -1;
+
+	vl53lx_dbgmsg("Enter\n");
+
+	rc = 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 != NULL)
+		stmvl53lx_module_func_tbl.clean_up();
+	vl53lx_dbgmsg("End\n");
+}
+
+int stmvl53lx_init_i2c(void)
+{
+	int ret = 0;
+
+	vl53lx_dbgmsg("Enter\n");
+
+	ret = i2c_add_driver(&stmvl53lx_driver);
+	if (ret)
+		vl53lx_errmsg("%d erro ret:%d\n", __LINE__, ret);
+
+	if (!ret && force_device)
+		ret = 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 = 0;
+	struct i2c_data *data = (struct i2c_data *) object;
+
+	vl53lx_dbgmsg("Enter\n");
+
+	if (data->vdd) {
+		rc = regulator_enable(data->vdd);
+		if (rc) {
+			vl53lx_errmsg("fail to turn on regulator");
+			return rc;
+		}
+	} else if (data->pwren_gpio != -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 = (struct i2c_data *) i2c_object;
+	int rc = 0;
+
+	vl53lx_dbgmsg("Enter\n");
+
+	if (data->vdd) {
+		rc = regulator_disable(data->vdd);
+		if (rc)
+			vl53lx_errmsg("reg disable failed. rc=%d\n",
+				rc);
+	} else if (data->pwren_gpio != -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 = (struct i2c_data *) i2c_object;
+
+	vl53lx_dbgmsg("Enter\n");
+
+	rc = release_reset(data);
+	if (rc)
+		goto error;
+
+	data->vl53lx_data->is_delay_allowed = true;
+	rc = VL53LX_WaitDeviceBooted(&data->vl53lx_data->stdev);
+	data->vl53lx_data->is_delay_allowed = false;
+	if (rc) {
+		gpio_set_value(data->xsdn_gpio, 0);
+		vl53lx_errmsg("boot fail with error %d", rc);
+		data->vl53lx_data->last_error = rc;
+		rc = -EIO;
+	}
+
+error:
+	vl53lx_dbgmsg("End\n");
+	return rc;
+}
+
+int stmvl53lx_reset_hold_i2c(void *i2c_object)
+{
+	struct i2c_data *data = (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 = (struct i2c_data *)object;
+	if (i2c_data->irq < 0) {
+		*poll_mode = -1;
+		return 0;
+	}
+
+	i2c_data->msg_flag.unhandled_irq_vec = 0;
+	if (i2c_data->io_flag.intr_started) {
+		*poll_mode = 0;
+		return 0;
+	}
+
+	vl53lx_dbgmsg("to register_irq:%d\n", i2c_data->irq);
+	rc = request_threaded_irq(i2c_data->irq, NULL, stmvl53lx_irq_handler_i2c, IRQF_TRIGGER_FALLING|IRQF_ONESHOT, "vl53lx_interrupt", (void *)i2c_data);
+	if (rc) {
+		vl53lx_errmsg("fail to req threaded irq rc=%d\n", rc);
+		*poll_mode = 0;
+	} else {
+		vl53lx_dbgmsg("irq %d now handled\n", i2c_data->irq);
+		i2c_data->io_flag.intr_started = 1;
+		*poll_mode = 0;
+	}
+	return rc;
+}
+
+void *stmvl53lx_get(void *object)
+{
+	struct i2c_data *data = (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 = (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 = {
+	.init = stmvl53lx_init_i2c,
+	.deinit = stmvl53lx_exit_i2c,
+	.power_up = stmvl53lx_power_up_i2c,
+	.power_down = stmvl53lx_power_down_i2c,
+	.reset_release = stmvl53lx_reset_release_i2c,
+	.reset_hold = stmvl53lx_reset_hold_i2c,
+	.clean_up = stmvl53lx_clean_up_i2c,
+	.start_intr = stmvl53lx_start_intr,
+	.get = stmvl53lx_get,
+	.put = stmvl53lx_put,
+};
+
+module_init(stmvl53lx_init);
+module_exit(stmvl53lx_exit);
+
+MODULE_AUTHOR("Song Qiang <songqiang1304521@...il.com>");
+MODULE_DESCRIPTION("ST vl53l4cx ToF ranging sensor driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ