summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/platform/msm/vidc/msm_v4l2_vidc.c10
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.c21
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.h17
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c121
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c5
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.h1
6 files changed, 155 insertions, 20 deletions
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index c0271c757020..de5a2dececdf 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -230,6 +230,14 @@ static int msm_v4l2_queryctrl(struct file *file, void *fh,
return msm_vidc_query_ctrl((void *)vidc_inst, ctrl);
}
+static int msm_v4l2_query_ext_ctrl(struct file *file, void *fh,
+ struct v4l2_query_ext_ctrl *ctrl)
+{
+ struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+
+ return msm_vidc_query_ext_ctrl((void *)vidc_inst, ctrl);
+}
+
static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
.vidioc_querycap = msm_v4l2_querycap,
.vidioc_enum_fmt_vid_cap_mplane = msm_v4l2_enum_fmt,
@@ -247,6 +255,7 @@ static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
.vidioc_s_ctrl = msm_v4l2_s_ctrl,
.vidioc_g_ctrl = msm_v4l2_g_ctrl,
.vidioc_queryctrl = msm_v4l2_queryctrl,
+ .vidioc_query_ext_ctrl = msm_v4l2_query_ext_ctrl,
.vidioc_s_ext_ctrls = msm_v4l2_s_ext_ctrl,
.vidioc_subscribe_event = msm_v4l2_subscribe_event,
.vidioc_unsubscribe_event = msm_v4l2_unsubscribe_event,
@@ -321,6 +330,7 @@ static int msm_vidc_initialize_core(struct platform_device *pdev,
init_completion(&core->completions[i]);
}
+ msm_comm_sort_ctrl();
INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler);
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 0764a18a7993..28a4006b480c 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -11,6 +11,7 @@
*
*/
+#include <linux/sort.h>
#include <linux/slab.h>
#include <soc/qcom/scm.h>
#include "msm_vidc_internal.h"
@@ -18,6 +19,7 @@
#include "vidc_hfi_api.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_dcvs.h"
+#include "msm_vdec.h"
#define MSM_VDEC_DVC_NAME "msm_vdec_8974"
#define MIN_NUM_OUTPUT_BUFFERS 4
@@ -553,6 +555,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
(1 << V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC)
),
.qmenu = mpeg_vidc_video_dpb_color_format,
+ .flags = V4L2_CTRL_FLAG_MODIFY_LAYOUT,
},
{
.id = V4L2_CID_VIDC_QBUF_MODE,
@@ -2814,3 +2817,21 @@ int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
return msm_comm_ctrl_init(inst, msm_vdec_ctrls,
ARRAY_SIZE(msm_vdec_ctrls), &msm_vdec_ctrl_ops);
}
+
+void msm_vdec_g_ctrl(struct msm_vidc_ctrl **ctrls, int *num_ctrls)
+{
+ *ctrls = msm_vdec_ctrls;
+ *num_ctrls = NUM_CTRLS;
+}
+
+static int msm_vdec_ctrl_cmp(const void *st1, const void *st2)
+{
+ return (int32_t)((struct msm_vidc_ctrl *)st1)->id -
+ (int32_t)((struct msm_vidc_ctrl *)st2)->id;
+}
+
+void msm_vdec_ctrl_sort(void)
+{
+ sort(msm_vdec_ctrls, NUM_CTRLS, sizeof(struct msm_vidc_ctrl),
+ msm_vdec_ctrl_cmp, NULL);
+}
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.h b/drivers/media/platform/msm/vidc/msm_vdec.h
index 47426c143c08..227cc99242d8 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.h
+++ b/drivers/media/platform/msm/vidc/msm_vdec.h
@@ -18,12 +18,13 @@
int msm_vdec_inst_init(struct msm_vidc_inst *inst);
int msm_vdec_ctrl_init(struct msm_vidc_inst *inst);
-int msm_vdec_querycap(void *instance, struct v4l2_capability *cap);
-int msm_vdec_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
-int msm_vdec_s_fmt(void *instance, struct v4l2_format *f);
-int msm_vdec_g_fmt(void *instance, struct v4l2_format *f);
-int msm_vdec_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
-int msm_vdec_reqbufs(void *instance, struct v4l2_requestbuffers *b);
+int msm_vdec_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap);
+int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f);
+int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
+int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
+int msm_vdec_s_ext_ctrl(struct msm_vidc_inst *inst,
+ struct v4l2_ext_controls *a);
+int msm_vdec_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b);
int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
int msm_vdec_release_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
@@ -32,6 +33,8 @@ int msm_vdec_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
int msm_vdec_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec);
int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
-struct vb2_ops *msm_vdec_get_vb2q_ops(void);
+const struct vb2_ops *msm_vdec_get_vb2q_ops(void);
+void msm_vdec_g_ctrl(struct msm_vidc_ctrl **ctrls, int *num_ctrls);
+void msm_vdec_ctrl_sort(void);
#endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 3e4be4418f80..f3d50c6a1e0c 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -14,13 +14,14 @@
#include <linux/dma-direction.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/bsearch.h>
+#include <linux/delay.h>
#include <media/msm_vidc.h>
#include "msm_vidc_internal.h"
#include "msm_vidc_debug.h"
#include "msm_vdec.h"
#include "msm_venc.h"
#include "msm_vidc_common.h"
-#include <linux/delay.h>
#include "vidc_hfi_api.h"
#include "msm_vidc_dcvs.h"
@@ -88,7 +89,7 @@ int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
return -EINVAL;
if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_querycap(instance, cap);
+ return msm_vdec_querycap(inst, cap);
else if (inst->session_type == MSM_VIDC_ENCODER)
return msm_venc_querycap(instance, cap);
return -EINVAL;
@@ -103,7 +104,7 @@ int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
return -EINVAL;
if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_enum_fmt(instance, f);
+ return msm_vdec_enum_fmt(inst, f);
else if (inst->session_type == MSM_VIDC_ENCODER)
return msm_venc_enum_fmt(instance, f);
return -EINVAL;
@@ -138,6 +139,101 @@ int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl)
}
EXPORT_SYMBOL(msm_vidc_query_ctrl);
+static int msm_vidc_queryctrl_bsearch_cmp1(const void *key, const void *elt)
+{
+ return *(int32_t *)key - (int32_t)((struct msm_vidc_ctrl *)elt)->id;
+}
+
+static int msm_vidc_queryctrl_bsearch_cmp2(const void *key, const void *elt)
+{
+ uint32_t id = *(uint32_t *)key;
+ struct msm_vidc_ctrl *ctrl = (struct msm_vidc_ctrl *)elt;
+
+ if (id >= ctrl[0].id && id < ctrl[1].id)
+ return 0;
+ else if (id < ctrl[0].id)
+ return -1;
+ else
+ return 1;
+}
+
+int msm_vidc_query_ext_ctrl(void *instance, struct v4l2_query_ext_ctrl *ctrl)
+{
+ struct msm_vidc_inst *inst = instance;
+ bool get_next_ctrl = 0;
+ int i, num_ctrls, rc = 0;
+ struct msm_vidc_ctrl *key = NULL;
+ struct msm_vidc_ctrl *msm_vdec_ctrls;
+
+ if (!inst || !ctrl)
+ return -EINVAL;
+
+ i = ctrl->id;
+ memset(ctrl, 0, sizeof(struct v4l2_query_ext_ctrl));
+ ctrl->id = i;
+
+ if (ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL)
+ get_next_ctrl = 1;
+ else if (ctrl->id & V4L2_CTRL_FLAG_NEXT_COMPOUND)
+ goto query_ext_ctrl_err;
+
+ ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
+ ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_COMPOUND;
+
+ if (ctrl->id > V4L2_CID_PRIVATE_BASE ||
+ (ctrl->id >= V4L2_CID_BASE && ctrl->id <= V4L2_CID_LASTP1))
+ goto query_ext_ctrl_err;
+ else if (ctrl->id == V4L2_CID_PRIVATE_BASE && get_next_ctrl)
+ ctrl->id = V4L2_CID_MPEG_MSM_VIDC_BASE;
+
+ if (inst->session_type == MSM_VIDC_DECODER)
+ msm_vdec_g_ctrl(&msm_vdec_ctrls, &num_ctrls);
+ else
+ return -EINVAL;
+
+ if (!get_next_ctrl)
+ key = bsearch(&ctrl->id, msm_vdec_ctrls, num_ctrls,
+ sizeof(struct msm_vidc_ctrl),
+ msm_vidc_queryctrl_bsearch_cmp1);
+ else {
+ key = bsearch(&ctrl->id, msm_vdec_ctrls, num_ctrls-1,
+ sizeof(struct msm_vidc_ctrl),
+ msm_vidc_queryctrl_bsearch_cmp2);
+
+ if (key && ctrl->id > key->id)
+ key++;
+ if (key) {
+ for (i = key-msm_vdec_ctrls, key = NULL;
+ i < num_ctrls; i++)
+ if (!(msm_vdec_ctrls[i].flags &
+ V4L2_CTRL_FLAG_DISABLED)) {
+ key = &msm_vdec_ctrls[i];
+ break;
+ }
+ }
+ }
+
+ if (key) {
+ ctrl->id = key->id;
+ ctrl->type = key->type;
+ strlcpy(ctrl->name, key->name, MAX_NAME_LENGTH);
+ ctrl->minimum = key->minimum;
+ ctrl->maximum = key->maximum;
+ ctrl->step = key->step;
+ ctrl->default_value = key->default_value;
+ ctrl->flags = key->flags;
+ ctrl->elems = 1;
+ ctrl->nr_of_dims = 0;
+ return rc;
+ }
+
+query_ext_ctrl_err:
+ ctrl->name[0] = '\0';
+ ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+ return -EINVAL;
+}
+EXPORT_SYMBOL(msm_vidc_query_ext_ctrl);
+
int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
{
struct msm_vidc_inst *inst = instance;
@@ -146,7 +242,7 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
return -EINVAL;
if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_s_fmt(instance, f);
+ return msm_vdec_s_fmt(inst, f);
if (inst->session_type == MSM_VIDC_ENCODER)
return msm_venc_s_fmt(instance, f);
return -EINVAL;
@@ -161,7 +257,7 @@ int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
return -EINVAL;
if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_g_fmt(instance, f);
+ return msm_vdec_g_fmt(inst, f);
else if (inst->session_type == MSM_VIDC_ENCODER)
return msm_venc_g_fmt(instance, f);
return -EINVAL;
@@ -197,7 +293,7 @@ int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *control)
return -EINVAL;
if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_s_ext_ctrl(instance, control);
+ return msm_vdec_s_ext_ctrl(inst, control);
if (inst->session_type == MSM_VIDC_ENCODER)
return msm_venc_s_ext_ctrl(instance, control);
return -EINVAL;
@@ -212,7 +308,7 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
return -EINVAL;
if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_reqbufs(instance, b);
+ return msm_vdec_reqbufs(inst, b);
if (inst->session_type == MSM_VIDC_ENCODER)
return msm_venc_reqbufs(instance, b);
return -EINVAL;
@@ -749,7 +845,7 @@ int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b)
return -EINVAL;
if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_prepare_buf(instance, b);
+ return msm_vdec_prepare_buf(inst, b);
if (inst->session_type == MSM_VIDC_ENCODER)
return msm_venc_prepare_buf(instance, b);
return -EINVAL;
@@ -816,8 +912,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type)
if (!release_buf)
continue;
if (inst->session_type == MSM_VIDC_DECODER)
- rc = msm_vdec_release_buf(instance,
- &buffer_info);
+ rc = msm_vdec_release_buf(inst, &buffer_info);
if (inst->session_type == MSM_VIDC_ENCODER)
rc = msm_venc_release_buf(instance,
&buffer_info);
@@ -944,7 +1039,7 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
}
if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_qbuf(instance, b);
+ return msm_vdec_qbuf(inst, b);
if (inst->session_type == MSM_VIDC_ENCODER)
return msm_venc_qbuf(instance, b);
@@ -1030,7 +1125,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type i)
return -EINVAL;
if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_streamon(instance, i);
+ return msm_vdec_streamon(inst, i);
if (inst->session_type == MSM_VIDC_ENCODER)
return msm_venc_streamon(instance, i);
return -EINVAL;
@@ -1045,7 +1140,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i)
return -EINVAL;
if (inst->session_type == MSM_VIDC_DECODER)
- return msm_vdec_streamoff(instance, i);
+ return msm_vdec_streamoff(inst, i);
if (inst->session_type == MSM_VIDC_ENCODER)
return msm_venc_streamoff(instance, i);
return -EINVAL;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index c9a871bae25b..f85fe6fd3867 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -22,6 +22,7 @@
#include "vidc_hfi_api.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_dcvs.h"
+#include "msm_vdec.h"
#define IS_ALREADY_IN_STATE(__p, __d) ({\
int __rc = (__p >= __d);\
@@ -5433,3 +5434,7 @@ static void msm_comm_print_debug_info(struct msm_vidc_inst *inst)
}
mutex_unlock(&core->lock);
}
+void msm_comm_sort_ctrl(void)
+{
+ msm_vdec_ctrl_sort();
+}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
index 01c1890bf5e1..7d28859c040c 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h
@@ -99,4 +99,5 @@ void msm_comm_cleanup_internal_buffers(struct msm_vidc_inst *inst);
int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
bool msm_comm_turbo_session(struct msm_vidc_inst *inst);
void msm_comm_print_inst_info(struct msm_vidc_inst *inst);
+void msm_comm_sort_ctrl(void);
#endif