diff options
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c | 126 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.h | 6 | ||||
| -rw-r--r-- | include/uapi/media/msm_cam_sensor.h | 12 |
3 files changed, 139 insertions, 5 deletions
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c index c12e95d3310a..83a9d8a10753 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/of_gpio.h> +#include <linux/leds-qpnp-flash.h> #include "msm_flash.h" #include "msm_camera_dt_util.h" #include "msm_cci.h" @@ -491,6 +492,45 @@ static int32_t msm_flash_init( return 0; } +static int32_t msm_flash_prepare( + struct msm_flash_ctrl_t *flash_ctrl) +{ + int32_t ret = 0; + + CDBG("%s:%d: State : %d\n", + __func__, __LINE__, flash_ctrl->flash_state); + + if (flash_ctrl->switch_trigger == NULL) { + pr_err("%s:%d Invalid argument\n", + __func__, __LINE__); + return -EINVAL; + } + + if (flash_ctrl->flash_state == MSM_CAMERA_FLASH_INIT && + flash_ctrl->is_regulator_enabled == 0) { + ret = qpnp_flash_led_prepare(flash_ctrl->switch_trigger, + ENABLE_REGULATOR, NULL); + if (ret < 0) { + pr_err("%s:%d regulator enable failed ret = %d\n", + __func__, __LINE__, ret); + return ret; + } + flash_ctrl->is_regulator_enabled = 1; + } else if (flash_ctrl->flash_state == MSM_CAMERA_FLASH_RELEASE && + flash_ctrl->is_regulator_enabled) { + ret = qpnp_flash_led_prepare(flash_ctrl->switch_trigger, + DISABLE_REGULATOR, NULL); + if (ret < 0) { + pr_err("%s:%d regulator disable failed ret = %d\n", + __func__, __LINE__, ret); + return ret; + } + flash_ctrl->is_regulator_enabled = 0; + } + CDBG("%s:%d:Exit\n", __func__, __LINE__); + return ret; +} + static int32_t msm_flash_low( struct msm_flash_ctrl_t *flash_ctrl, struct msm_flash_cfg_data_t *flash_data) @@ -564,6 +604,29 @@ static int32_t msm_flash_high( return 0; } +static int32_t msm_flash_query_current( + struct msm_flash_ctrl_t *flash_ctrl, + struct msm_flash_query_data_t *flash_query_data) +{ + int32_t ret = -EINVAL; + int32_t max_current = -EINVAL; + + if (flash_ctrl->switch_trigger) { + ret = qpnp_flash_led_prepare(flash_ctrl->switch_trigger, + QUERY_MAX_CURRENT, &max_current); + if (ret < 0) { + pr_err("%s:%d Query max_avail_curr failed ret = %d\n", + __func__, __LINE__, ret); + return ret; + } + } + + flash_query_data->max_avail_curr = max_current; + CDBG("%s: %d: max_avail_curr : %d\n", __func__, __LINE__, + flash_query_data->max_avail_curr); + return 0; +} + static int32_t msm_flash_release( struct msm_flash_ctrl_t *flash_ctrl) { @@ -626,11 +689,55 @@ static int32_t msm_flash_config(struct msm_flash_ctrl_t *flash_ctrl, mutex_unlock(flash_ctrl->flash_mutex); + rc = msm_flash_prepare(flash_ctrl); + if (rc < 0) { + pr_err("%s:%d Enable/Disable Regulator failed ret = %d", + __func__, __LINE__, rc); + return rc; + } + CDBG("Exit %s type %d\n", __func__, flash_data->cfg_type); return rc; } +static int32_t msm_flash_query_data(struct msm_flash_ctrl_t *flash_ctrl, + void __user *argp) +{ + int32_t rc = -EINVAL, i = 0; + struct msm_flash_query_data_t *flash_query = + (struct msm_flash_query_data_t *) argp; + + CDBG("Enter %s type %d\n", __func__, flash_query->query_type); + + switch (flash_query->query_type) { + case FLASH_QUERY_CURRENT: + if (flash_ctrl->func_tbl && flash_ctrl->func_tbl-> + camera_flash_query_current != NULL) + rc = flash_ctrl->func_tbl-> + camera_flash_query_current( + flash_ctrl, flash_query); + else { + flash_query->max_avail_curr = 0; + for (i = 0; i < flash_ctrl->flash_num_sources; i++) { + flash_query->max_avail_curr += + flash_ctrl->flash_op_current[i]; + } + rc = 0; + CDBG("%s: max_avail_curr: %d\n", __func__, + flash_query->max_avail_curr); + } + break; + default: + rc = -EFAULT; + break; + } + + CDBG("Exit %s type %d\n", __func__, flash_query->query_type); + + return rc; +} + static long msm_flash_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { @@ -662,8 +769,11 @@ static long msm_flash_subdev_ioctl(struct v4l2_subdev *sd, pr_err("fctrl->func_tbl NULL\n"); return -EINVAL; } else { - return fctrl->func_tbl->camera_flash_release(fctrl); + fctrl->func_tbl->camera_flash_release(fctrl); + return msm_flash_prepare(fctrl); } + case VIDIOC_MSM_FLASH_QUERY_DATA: + return msm_flash_query_data(fctrl, argp); default: pr_err_ratelimited("invalid cmd %d\n", cmd); return -ENOIOCTLCMD; @@ -846,9 +956,14 @@ static int32_t msm_flash_get_pmic_source_info( "qcom,current", &fctrl->torch_op_current[i]); if (rc < 0) { - pr_err("current: read failed\n"); - of_node_put(torch_src_node); - continue; + rc = of_property_read_u32(torch_src_node, + "qcom,current-ma", + &fctrl->torch_op_current[i]); + if (rc < 0) { + pr_err("current: read failed\n"); + of_node_put(torch_src_node); + continue; + } } /* Read max-current */ @@ -1134,6 +1249,7 @@ static struct msm_flash_table msm_pmic_flash_table = { .camera_flash_off = msm_flash_off, .camera_flash_low = msm_flash_low, .camera_flash_high = msm_flash_high, + .camera_flash_query_current = msm_flash_query_current, }, }; @@ -1145,6 +1261,7 @@ static struct msm_flash_table msm_gpio_flash_table = { .camera_flash_off = msm_flash_off, .camera_flash_low = msm_flash_low, .camera_flash_high = msm_flash_high, + .camera_flash_query_current = NULL, }, }; @@ -1156,6 +1273,7 @@ static struct msm_flash_table msm_i2c_flash_table = { .camera_flash_off = msm_flash_i2c_write_setting_array, .camera_flash_low = msm_flash_i2c_write_setting_array, .camera_flash_high = msm_flash_i2c_write_setting_array, + .camera_flash_query_current = NULL, }, }; diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.h b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.h index c82e48cddcaf..f6ac16f57080 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.h +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2009-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -42,6 +42,9 @@ struct msm_flash_func_t { struct msm_flash_cfg_data_t *); int32_t (*camera_flash_high)(struct msm_flash_ctrl_t *, struct msm_flash_cfg_data_t *); + int32_t (*camera_flash_query_current)(struct msm_flash_ctrl_t *, + struct msm_flash_query_data_t *); + }; struct msm_flash_table { @@ -67,6 +70,7 @@ struct msm_flash_ctrl_t { /* Switch node to trigger led */ const char *switch_trigger_name; struct led_trigger *switch_trigger; + uint32_t is_regulator_enabled; /* Flash */ uint32_t flash_num_sources; diff --git a/include/uapi/media/msm_cam_sensor.h b/include/uapi/media/msm_cam_sensor.h index 5d340b9a2523..8da6f293397e 100644 --- a/include/uapi/media/msm_cam_sensor.h +++ b/include/uapi/media/msm_cam_sensor.h @@ -34,6 +34,9 @@ #define MAX_NUMBER_OF_STEPS 47 #define MAX_REGULATOR 5 +/*msm_flash_query_data_t query types*/ +#define FLASH_QUERY_CURRENT 1 + #define MSM_V4L2_PIX_FMT_META v4l2_fourcc('M', 'E', 'T', 'A') /* META */ #define MSM_V4L2_PIX_FMT_SBGGR14 v4l2_fourcc('B', 'G', '1', '4') /* 14 BGBG.. GRGR.. */ @@ -530,6 +533,12 @@ struct msm_flash_cfg_data_t { } cfg; }; +struct msm_flash_query_data_t { + int32_t flags; + int32_t query_type; + int32_t max_avail_curr; +}; + /* sensor init structures and enums */ enum msm_sensor_init_cfg_type_t { CFG_SINIT_PROBE, @@ -585,5 +594,8 @@ struct sensor_init_cfg_data { #define VIDIOC_MSM_OIS_CFG_DOWNLOAD \ _IOWR('V', BASE_VIDIOC_PRIVATE + 14, struct msm_ois_cfg_download_data) +#define VIDIOC_MSM_FLASH_QUERY_DATA \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 15, struct msm_flash_query_data_t) + #endif |
