summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c126
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.h6
-rw-r--r--include/uapi/media/msm_cam_sensor.h12
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