From 22bbe96e8760fbcf024e993616b5f3670bab5aa7 Mon Sep 17 00:00:00 2001 From: wangdw10 Date: Wed, 5 Jun 2019 15:56:11 +0800 Subject: [PATCH] doha: add vl53l0 laser driver Change-Id: I1e8d7e74727ee1a654463440afaa78b10cb75b51 Signed-off-by: wangdw10 Reviewed-on: https://gerrit.mot.com/1371958 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Chuanxin Guo Reviewed-by: Dawei Wang Reviewed-by: Huosheng Liao Submit-Approved: Jira Key --- drivers/input/misc/vl53L0/Kbuild | 28 ++- .../input/misc/vl53L0/stmvl53l0_module-cci.c | 4 +- .../input/misc/vl53L0/stmvl53l0_module-i2c.c | 231 ++++++++++++++++-- drivers/input/misc/vl53L0/stmvl53l0_module.c | 24 +- 4 files changed, 246 insertions(+), 41 deletions(-) diff --git a/drivers/input/misc/vl53L0/Kbuild b/drivers/input/misc/vl53L0/Kbuild index a1272a5c661f..d53a7c84513e 100644 --- a/drivers/input/misc/vl53L0/Kbuild +++ b/drivers/input/misc/vl53L0/Kbuild @@ -3,24 +3,28 @@ # # Each configuration option enables a list of files. -FEATURE_USE_CCI := true +FEATURE_USE_CCI := false ifeq ($(FEATURE_USE_CCI), true) -ccflags-y += -Idrivers/input/misc/vl53L0/inc -DCAMERA_CCI +EXTRA_CFLAGS += -DCAMERA_CCI else -ccflags-y += -Idrivers/input/misc/vl53L0/inc -DSTM_TEST +EXTRA_CFLAGS += -DSTM_TEST endif -ccflags-$(CONFIG_MSMB_CAMERA) += -Idrivers/media/platform/msm/camera_v2/sensor/io -ccflags-$(CONFIG_MSMB_CAMERA) += -Idrivers/media/platform/msm/camera_v2 -ccflags-$(CONFIG_MSMB_CAMERA) += -Idrivers/media/platform/msm/camera_v2/sensor/cci -ccflags-$(CONFIG_MSMB_CAMERA) += -Idrivers/media/platform/msm/camera_v2/common +EXTRA_CFLAGS += -Wall +EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/drivers/input/misc/vl53L0 +EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/drivers/input/misc/vl53L0/inc -ccflags-$(CONFIG_MSMB_CAMERA_2016) += -Idrivers/media/platform/msm/camera_v2_2016/sensor/io -ccflags-$(CONFIG_MSMB_CAMERA_2016) += -Idrivers/media/platform/msm/camera_v2_2016 -ccflags-$(CONFIG_MSMB_CAMERA_2016) += -Idrivers/media/platform/msm/camera_v2_2016/sensor/cci -ccflags-$(CONFIG_MSMB_CAMERA_2016) += -Idrivers/media/platform/msm/camera_v2_2016/common +EXTRA_CFLAGS += -I$(TOP)/kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/io +EXTRA_CFLAGS += -I$(TOP)/kernel/msm-4.14/drivers/media/platform/msm/camera_v2 +EXTRA_CFLAGS += -I$(TOP)/kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/cci +EXTRA_CFLAGS += -I$(TOP)/kernel/msm-4.14/drivers/media/platform/msm/camera_v2/common obj-m += stmvl53l0.o -stmvl53l0-objs := stmvl53l0_module.o stmvl53l0_module-i2c.o stmvl53l0_module-cci.o src/vl53l0_api_calibration.o src/vl53l0_api_core.o src/vl53l0_api_histogram.o src/vl53l0_api_ranging.o src/vl53l0_api_strings.o src/vl53l0_api.o src/vl53l0_platform.o src/vl53l0_i2c_platform.o src/vl53l0_port_i2c.o src/vl53l010_api.o src/vl53l010_tuning.o +stmvl53l0-objs := stmvl53l0_module.o stmvl53l0_module-i2c.o +stmvl53l0-objs += src/vl53l0_api_calibration.o src/vl53l0_api_core.o +stmvl53l0-objs += src/vl53l0_api_histogram.o src/vl53l0_api_ranging.o +stmvl53l0-objs += src/vl53l0_api_strings.o src/vl53l0_api.o src/vl53l0_platform.o +stmvl53l0-objs += src/vl53l0_i2c_platform.o src/vl53l0_port_i2c.o +stmvl53l0-objs += src/vl53l010_api.o src/vl53l010_tuning.o diff --git a/drivers/input/misc/vl53L0/stmvl53l0_module-cci.c b/drivers/input/misc/vl53L0/stmvl53l0_module-cci.c index 74c5c9077502..578f7c04af17 100644 --- a/drivers/input/misc/vl53L0/stmvl53l0_module-cci.c +++ b/drivers/input/misc/vl53L0/stmvl53l0_module-cci.c @@ -52,7 +52,7 @@ #include "stmvl53l0.h" #define LASER_SENSOR_PINCTRL_STATE_SLEEP "laser_suspend" #define LASER_SENSOR_PINCTRL_STATE_DEFAULT "laser_default" - +#ifdef CAMERA_CCI /* * Global data */ @@ -472,4 +472,4 @@ void stmvl53l0_exit_cci(void *cci_object) vl53l0_dbgmsg("End\n"); } - +#endif /* end of CAMERA_CCI */ diff --git a/drivers/input/misc/vl53L0/stmvl53l0_module-i2c.c b/drivers/input/misc/vl53L0/stmvl53l0_module-i2c.c index 6bc4f390ebfa..f20f68e568c8 100644 --- a/drivers/input/misc/vl53L0/stmvl53l0_module-i2c.c +++ b/drivers/input/misc/vl53L0/stmvl53l0_module-i2c.c @@ -131,6 +131,189 @@ int get_dt_threshold_data(struct device_node *of_node, int *lowv, int *highv) return rc; } +static int stmvl53l0_get_dt_gpio_req_tbl(struct device_node *of_node, + struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array, + uint16_t gpio_array_size) +{ + int rc = 0, i = 0; + uint32_t count = 0; + uint32_t *val_array = NULL; + + if (!of_get_property(of_node, "qcom,gpio-req-tbl-num", &count)) + return 0; + + count /= sizeof(uint32_t); + if (!count) { + pr_err("%s qcom,gpio-req-tbl-num 0\n", __func__); + return 0; + } + + val_array = kcalloc(count, sizeof(uint32_t), GFP_KERNEL); + if (!val_array) + return -ENOMEM; + + gconf->cam_gpio_req_tbl = kcalloc(count, sizeof(struct gpio), + GFP_KERNEL); + if (!gconf->cam_gpio_req_tbl) { + rc = -ENOMEM; + goto ERROR1; + } + gconf->cam_gpio_req_tbl_size = count; + + rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-num", + val_array, count); + if (rc < 0) { + pr_err("%s failed %d\n", __func__, __LINE__); + goto ERROR2; + } + for (i = 0; i < count; i++) { + if (val_array[i] >= gpio_array_size) { + pr_err("%s gpio req tbl index %d invalid\n", + __func__, val_array[i]); + return -EINVAL; + } + gconf->cam_gpio_req_tbl[i].gpio = gpio_array[val_array[i]]; + vl53l0_dbgmsg("cam_gpio_req_tbl[%d].gpio = %d\n", i, + gconf->cam_gpio_req_tbl[i].gpio); + } + + rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-flags", + val_array, count); + if (rc < 0) { + pr_err("%s failed %d\n", __func__, __LINE__); + goto ERROR2; + } + for (i = 0; i < count; i++) { + gconf->cam_gpio_req_tbl[i].flags = val_array[i]; + vl53l0_dbgmsg("cam_gpio_req_tbl[%d].flags = %ld\n", i, + gconf->cam_gpio_req_tbl[i].flags); + } + + for (i = 0; i < count; i++) { + rc = of_property_read_string_index(of_node, + "qcom,gpio-req-tbl-label", i, + &gconf->cam_gpio_req_tbl[i].label); + vl53l0_dbgmsg("cam_gpio_req_tbl[%d].label = %s\n", i, + gconf->cam_gpio_req_tbl[i].label); + if (rc < 0) { + pr_err("%s failed %d\n", __func__, __LINE__); + goto ERROR2; + } + } + + kfree(val_array); + return rc; + +ERROR2: + kfree(gconf->cam_gpio_req_tbl); +ERROR1: + kfree(val_array); + gconf->cam_gpio_req_tbl_size = 0; + return rc; +} + +static int stmvl53l0_init_gpio_pin_tbl(struct device_node *of_node, + struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array, + uint16_t gpio_array_size) +{ + int rc = 0, val = 0; + + gconf->gpio_num_info = kzalloc(sizeof(struct msm_camera_gpio_num_info), + GFP_KERNEL); + if (!gconf->gpio_num_info) { + rc = -ENOMEM; + return rc; + } + + rc = of_property_read_u32(of_node, "qcom,gpio-vana", &val); + if (rc != -EINVAL) { + if (rc < 0) { + pr_err("%s:%d read qcom,gpio-vana failed rc %d\n", + __func__, __LINE__, rc); + goto ERROR; + } else if (val >= gpio_array_size) { + pr_err("%s:%d qcom,gpio-vana invalid %d\n", + __func__, __LINE__, val); + rc = -EINVAL; + goto ERROR; + } + gconf->gpio_num_info->gpio_num[1] = + gpio_array[val]; + gconf->gpio_num_info->valid[1] = 1; + vl53l0_dbgmsg("qcom,gpio-vana %d\n", + gconf->gpio_num_info->gpio_num[1]); + } else { + rc = 0; + } + + rc = of_property_read_u32(of_node, "qcom,gpio-reset", &val); + if (rc != -EINVAL) { + if (rc < 0) { + pr_err("%s:%d read qcom,gpio-reset failed rc %d\n", + __func__, __LINE__, rc); + goto ERROR; + } else if (val >= gpio_array_size) { + pr_err("%s:%d qcom,gpio-reset invalid %d\n", + __func__, __LINE__, val); + rc = -EINVAL; + goto ERROR; + } + gconf->gpio_num_info->gpio_num[0] = + gpio_array[val]; + gconf->gpio_num_info->valid[0] = 1; + vl53l0_dbgmsg("qcom,gpio-reset %d\n", + gconf->gpio_num_info->gpio_num[0]); + } else { + rc = 0; + } + + return rc; + +ERROR: + kfree(gconf->gpio_num_info); + gconf->gpio_num_info = NULL; + return rc; +} + + +static void stmvl53l0_request_gpio_table(struct gpio *gpio_tbl, uint8_t size, + int gpio_en) +{ + int i = 0, err = 1, retry_count = 0; + + if (!gpio_tbl || !size) { + pr_err("%s:%d invalid gpio_tbl %pK / size %d\n", __func__, + __LINE__, gpio_tbl, size); + } + for (i = 0; i < size; i++) { + vl53l0_dbgmsg("%d i %d, gpio %d dir %ld\n", __LINE__, i, + gpio_tbl[i].gpio, gpio_tbl[i].flags); + } + if (gpio_en) { + while (err && retry_count < 10) { + for (i = 0; i < size; i++) { + err = gpio_request_one(gpio_tbl[i].gpio, + gpio_tbl[i].flags, gpio_tbl[i].label); + if (err) { + /* + * After GPIO request fails, contine to + * apply new gpios, outout a error message + * for driver bringup debug + */ + pr_err("%s:%d gpio %d:%s request fails, retry_count %d\n", + __func__, __LINE__, + gpio_tbl[i].gpio, gpio_tbl[i].label, retry_count); + msleep(30); + retry_count++; + break; + } + } + } + } else { + gpio_free_array(gpio_tbl, size); + } +} + static int stmvl53l0_get_dt_data(struct device *dev, struct i2c_data *data) { int rc = 0; @@ -175,7 +358,7 @@ static int stmvl53l0_get_dt_data(struct device *dev, struct i2c_data *data) gpio_array[i]); } - rc = msm_camera_get_dt_gpio_req_tbl(of_node, gconf, + rc = stmvl53l0_get_dt_gpio_req_tbl(of_node, gconf, gpio_array, gpio_array_size); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); @@ -183,7 +366,7 @@ static int stmvl53l0_get_dt_data(struct device *dev, struct i2c_data *data) return rc; } - rc = msm_camera_init_gpio_pin_tbl(of_node, gconf, + rc = stmvl53l0_init_gpio_pin_tbl(of_node, gconf, gpio_array, gpio_array_size); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); @@ -267,8 +450,8 @@ static int stmvl53l0_probe(struct i2c_client *client, if (rc != 0) { vl53l0_errmsg("%d,error rc %d\n", __LINE__, rc); stmvl53l0_power_down_i2c(i2c_object); - return rc; } + stmvl53l0_power_down_i2c(i2c_object); rc = stmvl53l0_setup(vl53l0_data, I2C_BUS); @@ -301,6 +484,7 @@ static const struct of_device_id st_stmvl53l0_dt_match[] = { { }, }; +/* int stmv153l0_resume(struct i2c_client *clt) { struct stmvl53l0_data *vl53l0_data = NULL; @@ -310,8 +494,9 @@ int stmv153l0_resume(struct i2c_client *clt) stmvl53l0_livechecking(vl53l0_data); return 0; } +*/ -static struct i2c_driver stmvl6180_driver = { +static struct i2c_driver stmvl53l0_driver = { .driver = { .name = STMVL53L0_DRV_NAME, .owner = THIS_MODULE, @@ -319,7 +504,7 @@ static struct i2c_driver stmvl6180_driver = { }, .probe = stmvl53l0_probe, .remove = stmvl53l0_remove, - .resume = stmv153l0_resume, + /* .resume = stmv153l0_resume, */ .id_table = stmvl53l0_id, }; @@ -331,8 +516,6 @@ int stmvl53l0_power_up_i2c(void *i2c_object, unsigned int *preset_flag) struct i2c_data *data = (struct i2c_data *)i2c_object; vl53l0_dbgmsg("Enter i2c powerup\n"); - pinctrl_select_state(data->pinctrl_info.pinctrl, - data->pinctrl_info.gpio_state_active); if (!IS_ERR(data->vana)) { ret = regulator_set_voltage(data->vana, VL53L0_VDD_MIN, @@ -350,11 +533,22 @@ int stmvl53l0_power_up_i2c(void *i2c_object, unsigned int *preset_flag) } } - msm_camera_request_gpio_table( + stmvl53l0_request_gpio_table( data->gconf.cam_gpio_req_tbl, data->gconf.cam_gpio_req_tbl_size, 1); + pinctrl_select_state(data->pinctrl_info.pinctrl, + data->pinctrl_info.gpio_state_active); + + gpio_set_value_cansleep(data->gconf.cam_gpio_req_tbl[1].gpio, 1); + vl53l0_dbgmsg("Enable gpio%d\n",data->gconf.cam_gpio_req_tbl[1].gpio ); + msleep(20); gpio_set_value_cansleep(data->gconf.cam_gpio_req_tbl[0].gpio, 1); + vl53l0_dbgmsg("Enable gpio%d\n",data->gconf.cam_gpio_req_tbl[0].gpio ); + + stmvl53l0_request_gpio_table( + data->gconf.cam_gpio_req_tbl, + data->gconf.cam_gpio_req_tbl_size, 0); data->power_up = 1; *preset_flag = 1; @@ -371,15 +565,23 @@ int stmvl53l0_power_down_i2c(void *i2c_object) vl53l0_dbgmsg("Enter\n"); if (data->power_up) { + stmvl53l0_request_gpio_table( + data->gconf.cam_gpio_req_tbl, + data->gconf.cam_gpio_req_tbl_size, 1); + pinctrl_select_state(data->pinctrl_info.pinctrl, data->pinctrl_info.gpio_state_suspend); - msm_camera_request_gpio_table( - data->gconf.cam_gpio_req_tbl, - data->gconf.cam_gpio_req_tbl_size, 0); - gpio_set_value_cansleep( data->gconf.cam_gpio_req_tbl[0].gpio, 0); + vl53l0_dbgmsg("Disable gpio%d\n",data->gconf.cam_gpio_req_tbl[0].gpio ); + gpio_set_value_cansleep( + data->gconf.cam_gpio_req_tbl[1].gpio, 0); + vl53l0_dbgmsg("Disable gpio%d\n",data->gconf.cam_gpio_req_tbl[1].gpio ); + + stmvl53l0_request_gpio_table( + data->gconf.cam_gpio_req_tbl, + data->gconf.cam_gpio_req_tbl_size, 0); if (!IS_ERR(data->vana)) { ret = regulator_disable(data->vana); @@ -391,7 +593,6 @@ int stmvl53l0_power_down_i2c(void *i2c_object) data->power_up = 0; } - vl53l0_dbgmsg("End\n"); return ret; } @@ -403,7 +604,7 @@ int stmvl53l0_init_i2c(void) vl53l0_dbgmsg("Enter\n"); /* register as a i2c client device */ - ret = i2c_add_driver(&stmvl6180_driver); + ret = i2c_add_driver(&stmvl53l0_driver); if (ret) vl53l0_errmsg("%d erro ret:%d\n", __LINE__, ret); @@ -415,7 +616,7 @@ int stmvl53l0_init_i2c(void) void stmvl53l0_exit_i2c(void *i2c_object) { vl53l0_dbgmsg("Enter\n"); - i2c_del_driver(&stmvl6180_driver); + i2c_del_driver(&stmvl53l0_driver); vl53l0_dbgmsg("End\n"); } diff --git a/drivers/input/misc/vl53L0/stmvl53l0_module.c b/drivers/input/misc/vl53L0/stmvl53l0_module.c index 9ed08dc27af9..a93dcd1dd243 100644 --- a/drivers/input/misc/vl53L0/stmvl53l0_module.c +++ b/drivers/input/misc/vl53L0/stmvl53l0_module.c @@ -65,20 +65,21 @@ static struct stmvl53l0_data *gp_vl53l0_data; static int s_count; static int s_prevalue; -static struct stmvl53l0_module_fn_t stmvl53l0_module_func_tbl_cci = { +#ifdef CAMERA_CCI +static struct stmvl53l0_module_fn_t stmvl53l0_module_func_tbl = { .init = stmvl53l0_init_cci, .deinit = stmvl53l0_exit_cci, .power_up = stmvl53l0_power_up_cci, .power_down = stmvl53l0_power_down_cci, }; - -static struct stmvl53l0_module_fn_t stmvl53l0_module_func_tbl_i2c = { +#else +static struct stmvl53l0_module_fn_t stmvl53l0_module_func_tbl = { .init = stmvl53l0_init_i2c, .deinit = stmvl53l0_exit_i2c, .power_up = stmvl53l0_power_up_i2c, .power_down = stmvl53l0_power_down_i2c, }; - +#endif struct stmvl53l0_module_fn_t *pmodule_func_tbl; static struct stmvl53l0_parameter s_parameters[10]; static int s_nump; @@ -2578,23 +2579,23 @@ int stmvl53l0_setup(struct stmvl53l0_data *data, uint8_t type) data->bus_type = CCI_BUS; data->client_object = &(data->cci_client_object); /* assign function table */ - pmodule_func_tbl = &stmvl53l0_module_func_tbl_cci; - gpio = data->cci_client_object.gconf.cam_gpio_req_tbl[1].gpio; + pmodule_func_tbl = &stmvl53l0_module_func_tbl; + gpio = data->cci_client_object.gconf.cam_gpio_req_tbl[2].gpio; data->lowv = data->cci_client_object.lowv; data->highv = data->cci_client_object.highv; data->xtalk = data->cci_client_object.xtalk; } else { data->bus_type = I2C_BUS; data->client_object = &(data->i2c_client_object); - pmodule_func_tbl = &stmvl53l0_module_func_tbl_i2c; - gpio = data->i2c_client_object.gconf.cam_gpio_req_tbl[1].gpio; + pmodule_func_tbl = &stmvl53l0_module_func_tbl; + gpio = data->i2c_client_object.gconf.cam_gpio_req_tbl[2].gpio; data->lowv = data->i2c_client_object.lowv; data->highv = data->i2c_client_object.highv; data->xtalk = data->i2c_client_object.xtalk; } - /* init interrupt */ - gpio_request(gpio, "vl6180_gpio_int"); + gpio_request(gpio, "vl53l0_gpio_int"); + vl53l0_dbgmsg("gpio_request %d to register_irq\n", gpio); gpio_direction_input(gpio); irq = gpio_to_irq(gpio); @@ -2754,8 +2755,7 @@ static int __init stmvl53l0_init(void) /* assign function table */ papi_func_tbl = &stmvl53l0_api_func_tbl; /* client specific init function */ - stmvl53l0_module_func_tbl_i2c.init(); - stmvl53l0_module_func_tbl_cci.init(); + stmvl53l0_module_func_tbl.init(); if (ret) { kfree(vl53l0_data);