[PATCH] tof: Add VL53L4CX TOF drivers

434779359@qq.com posted 1 patch 19 hours ago
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
[PATCH] tof: Add VL53L4CX TOF drivers
Posted by 434779359@qq.com 19 hours ago
From: liufulin <frank.liu@faiot.com>

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

Signed-off-by: liufulin <frank.liu@faiot.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@gmail.com>
+ * Copyright (C) 2020 Ivan Drobyshevskyi <drobyshevskyi@gmail.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@gmail.com>");
+MODULE_DESCRIPTION("ST vl53l4cx ToF ranging sensor driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1
Re: [PATCH] tof: Add VL53L4CX TOF drivers
Posted by kernel test robot 3 hours ago
Hi,

kernel test robot noticed the following build errors:

[auto build test ERROR on jic23-iio/togreg]
[also build test ERROR on linus/master v6.19-rc8 next-20260205]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/434779359-qq-com/tof-Add-VL53L4CX-TOF-drivers/20260207-174646
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
patch link:    https://lore.kernel.org/r/tencent_326708D02875274DF25B10B91402B3828606%40qq.com
patch subject: [PATCH] tof: Add VL53L4CX TOF drivers
config: loongarch-randconfig-r122-20260208 (https://download.01.org/0day-ci/archive/20260208/202602081057.kWswynEJ-lkp@intel.com/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260208/202602081057.kWswynEJ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202602081057.kWswynEJ-lkp@intel.com/

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: input_set_abs_params
   >>> referenced by vl53l4cx-i2c.c:5614 (drivers/iio/proximity/vl53l4cx-i2c.c:5614)
   >>>               drivers/iio/proximity/vl53l4cx-i2c.o:(stmvl53lx_setup) in archive vmlinux.a
   >>> referenced by vl53l4cx-i2c.c:5615 (drivers/iio/proximity/vl53l4cx-i2c.c:5615)
   >>>               drivers/iio/proximity/vl53l4cx-i2c.o:(stmvl53lx_setup) in archive vmlinux.a
   >>> referenced by vl53l4cx-i2c.c:5616 (drivers/iio/proximity/vl53l4cx-i2c.c:5616)
   >>>               drivers/iio/proximity/vl53l4cx-i2c.o:(stmvl53lx_setup) in archive vmlinux.a
   >>> referenced 16 more times

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] tof: Add VL53L4CX TOF drivers
Posted by kernel test robot 12 hours ago
Hi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on jic23-iio/togreg]
[also build test WARNING on linus/master v6.19-rc8 next-20260205]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/434779359-qq-com/tof-Add-VL53L4CX-TOF-drivers/20260207-174646
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
patch link:    https://lore.kernel.org/r/tencent_326708D02875274DF25B10B91402B3828606%40qq.com
patch subject: [PATCH] tof: Add VL53L4CX TOF drivers
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20260208/202602080159.l0CRmkUf-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260208/202602080159.l0CRmkUf-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202602080159.l0CRmkUf-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/iio/proximity/vl53l4cx-i2c.c: In function 'ctrl_mz_data_blocking_common':
>> drivers/iio/proximity/vl53l4cx-i2c.c:16100:13: warning: variable 'rc0' set but not used [-Wunused-but-set-variable]
   16100 |         int rc0;
         |             ^~~


vim +/rc0 +16100 drivers/iio/proximity/vl53l4cx-i2c.c

 16096	
 16097	static int ctrl_mz_data_blocking_common(struct stmvl53lx_data *data, void __user *p, bool is_additional)
 16098	{
 16099		int rc = 0;
 16100		int rc0;
 16101		struct stmvl53lx_data_with_additional __user *d = p;
 16102		pid_t pid = current->pid;
 16103	
 16104		mutex_lock(&data->work_mutex);
 16105		if (data->is_device_remove) {
 16106			rc = -ENODEV;
 16107			goto done;
 16108		}
 16109		if (!data->enable_sensor) {
 16110			rc = -ENODEV;
 16111			goto done;
 16112		}
 16113		if (!is_new_data_for_me(data, pid, &data->mz_data_reader_list))
 16114			rc = sleep_for_data(data, pid, &data->mz_data_reader_list);
 16115		if (rc) {
 16116			kill_mz_data(&data->meas.multi_range_data);
 16117			rc0 = copy_to_user(&d->data, &data->meas.multi_range_data, sizeof(VL53LX_MultiRangingData_t));
 16118			goto done;
 16119		}
 16120	
 16121		rc = copy_to_user(&d->data, &data->meas.multi_range_data, sizeof(VL53LX_MultiRangingData_t));
 16122		if (rc)
 16123			goto done;
 16124		if (is_additional) {
 16125			rc = copy_to_user(&d->additional_data, &data->meas.additional_data, sizeof(VL53LX_AdditionalData_t));
 16126			if (rc)
 16127				goto done;
 16128		}
 16129		rc = add_reader(pid, &data->mz_data_reader_list);
 16130	
 16131	done:
 16132		mutex_unlock(&data->work_mutex);
 16133	
 16134		return rc;
 16135	}
 16136	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] tof: Add VL53L4CX TOF drivers
Posted by Jonathan Cameron 15 hours ago
On Sat,  7 Feb 2026 17:42:35 +0800
434779359@qq.com wrote:

> From: liufulin <frank.liu@faiot.com>
> 
> This patch adds support for the vl53l4cx tof ic
> ICs used in Qualcomm reference designs
> 
> Signed-off-by: liufulin <frank.liu@faiot.com>
Hi Frank and welcome to IIO.

This is a massive commit.  Normally roughly speaking each commit should
be an absolute maximum of 500-1000 lines of code because this what
people can realistically review in one go.

I'll take a superficial look at what you have here but to make any
progress towards upstream it will need stripping back to a much more
minimalist base.  From that we we can then look at adding more features
in future patch sets.

Note the largest drivers for what I'd expect to be a lot more complex
than a time of flight sensor are not as large as this in terms of
lines of code.

Look at the other commits to drivers/iio/ and follow the naming style
there.  e.g. something like
iio: proximity: Add VL...


> ---
>  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@gmail.com>
> + * Copyright (C) 2020 Ivan Drobyshevskyi <drobyshevskyi@gmail.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>
Follow include what you use principles for IIO drivers.
For instance I see this uses a mutex, so include the header for that.
Note that we only do an approximate version of IWYU as some headers
are guaranteed to include others by design - as opposed to coincidence.
  
> +
> +#include <linux/iio/iio.h>
> +#include <linux/miscdevice.h>

There should be no reason for an IIO driver to need this header.
An IIO driver does not normally register as other types of device
as well as an IIO one.  If that does make sense in the long run
(as opposed to using a bridge driver - of which we have several
already for crossing subsystem boundaries) then don't do it in the
initial driver. Propose it as a later enhancement.


> +#include <linux/of_gpio.h>

Whilst I haven't checked yet it would be very usual to need
to include of_gpio.h in an IIO driver. That may imply using wrong
level of interfaces or just a stray include.

> +#include <linux/input.h>

Should not need this one either.
> +
> +#define STMVL53LX_DRV_NAME	"stmvl53lx"

Driver names don't normally have the stm prefix.   Also I strongly
prefer to just see the string used inline as it is rare that there
is anything that requires the various places such defines are used
to have the same string and using such a define implies such a requirement.

> +#define STMVL53LX_SLAVE_ADDR	(0x52>>1)
This seems unlikely
> +
> +#define VL_REG_SYSRANGE_START				0x00
> +
> +#define MODI2C_DEBUG	0
> +
> +#if 0
> +#define DEBUG	1
> +#endif
> +#if 0
> +#define FORCE_CONSOLE_DEBUG
> +#endif
This sort of set of defines do not belong in a driver for upstream.
> +
> +extern int stmvl53lx_enable_debug;
This doesn't either. Particularly true as it's a single file, so extern

is not useful.

> +
> +#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__); \

We have dynamic debug in the kernel, use
dev_dbg() etc to replace all this and rely on standard runtime controls
to turn prints on and off.

> +} 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)

None of these should be used in a driver for upstream. Use
the standard calls. Dynamic debug allows you to control
what is printed included function names etc.

> +
> +#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
> +
Having looked quickly through the defines that follow 90% of them
should not be here. Only have defines for
1) Register addresses
2) Fields in registers (typically masks, sometimes values for enumeration
   like field values).
3) Key constants that are used repeatedly.

> +#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

The blank lines in here don't seem to provide much benefit for
readability.  Group the types of define together in blocks with
blank lines only used to separate those blocks. 

> +
> +#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
I have no idea why we have lots of defines to 0.  Drop all these.  There is
never any reason to define away errors.
> +
>
> +#define VL53LXDevDataGet(Dev, field) (Dev->field)
> +#define VL53LXDevDataSet(Dev, field, data) ((Dev->field) = (data))

These macros don't provide an obvious readability benefit over just
using the accesses to the relevant structures inline.  So please remove
them.


> +
> +#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;

Use kernel types u32 etc not uint32_t...


> +
> +#define VL53LX_FIXPOINT1616TOFIXPOINT44(Value) ((uint16_t)((Value>>12)&0xFFFF))

Define a mask for the fields if it adds clarity over
GENMASK(19, 12) being used inline in conjunction with FIELD_GET() / FIELD_PREP()

> +#define VL53LX_FIXPOINT44TOFIXPOINT1616(Value) ((FixPoint1616_t)((uint32_t)Value<<12))
> +
> +#define VL53LX_FIXPOINT1616TOFIXPOINT72(Value) ((uint16_t)((Value>>14)&0xFFFF))

> +
> +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)
These are very long definitions.  Feels like an enum would be appropriate
but maybe I'm missing something.


> +#define VL53LX_OSC_MEASURED__FAST_OSC__FREQUENCY 0x0006
> +#define VL53LX_OSC_MEASURED__FAST_OSC__FREQUENCY_HI 0x0006

One define for the first register involved should be enough.
No need for repeats.  If larger reads are used and as such
only ever the first define, then don't have defines for the
_LO register at all. It brings no advantage.


> +#define VL53LX_OSC_MEASURED__FAST_OSC__FREQUENCY_LO 0x0007

> +#define VL53LX_PATCH__OFFSET_0 0x0476

For large sets of registers like this that are just numbers use
a define that takes a parameter to cover all of them.
If you want to range check that parameter, then can use a little
helper function.

> +#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_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)
> +

An IIO driver should not have custom IOCTL.  Take these out for
now and once basic driver is in place we can discuss how to support
this sort of functionality.

> +
> +
> +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[];

Use __counted_by() here.  I assume cnt?

> +};
> +


> +#define IMPLEMENT_PARAMETER_INTEGER(sysfs_name, info_name)\
> +static ssize_t stmvl53lx_show_##sysfs_name(struct device *dev, \
> +				struct device_attribute *attr, char *buf) \
Custom attributes need documentation in 
Documentation/ABI/testing/sysfs-bus-iio-vl53l4cx

However, note that custom attributes often mean unused code, so I am very
conservative about allowing them.   Most of the time we can find
an existing interface, or propose new general interfaces to cover particular
features.

> +{ \
> +	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); \
> +} \
> +\

I skipped most of the rest of the defines as I'd expect the vast
majority not to be present in v2.  Maybe they will come back in future
patches adding additional features.


> +
> +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;

Drop the input device and misc device at least from initial patch.
If you do propose adding those in a future series, then you need
to cc linux-input.

> +	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;
Superficially I'd guess a log of the stuff in here is caching device
state.  Just read it back from the device registers.  Reading state
of devices is very rarely a fast path.

Perhaps regmap / regcache can be used here to reduce bus traffic
if that's a problem.

> +	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 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);
This looks like a hardware abstraction layer (HAL).  Whilst sometimes
we do end up with a few callbacks as a driver is expanded to include
additional devices, we do this only as needed. For now remove this
and use direct calls to the relevant functions.

> +};

> +
> +static struct i2c_client *stm_test_i2c_client;
No idea what this is. But by the name it doesn't belong in a
upstream driver.

> +
> +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");

Drop all these module parameters.  Any device specific information should come
from firmware, not module parameters.

> +
> +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);

I haven't looked in detail, but I would not expect to see more than a very
small number of forwards definitions in a driver.  Also follow standard
kernel style for type names etc.  I want to see struct .... for these
not a typedef.

> +VL53LX_Error VL53LX_get_device_results(VL53LX_DEV Dev, VL53LX_DeviceResultsLevel device_results_level, VL53LX_range_results_t *prange_results);
I'm going to stop here for today as I have a large backlog of code and I think
the comments to this point should get you going on stripping this driver
back for v2.

Remember to target an absolute maximum of 1000 lines for each patch. Preferably
a lot smaller that that.

For the full series, stay under 2000 lines or in practice it won't get reviewed.

Jonathan
Re: [PATCH] tof: Add VL53L4CX TOF drivers
Posted by Linus Walleij 7 hours ago
On Sat, Feb 7, 2026 at 2:50 PM Jonathan Cameron <jic23@kernel.org> wrote:
> 434779359@qq.com wrote:

> > +#include <linux/of_gpio.h>
>
> Whilst I haven't checked yet it would be very usual to need
> to include of_gpio.h in an IIO driver. That may imply using wrong
> level of interfaces or just a stray include.

This is a legacy header that should not be used in new
code.

<linux/gpio/consumer.h> should suffice for consumers,
<linux/gpio/driver.h> should suffice for producers.

Yours,
Linus Walleij