msm: ba: Merge relevant changes from A family

Merge relevant bridge abstraction changes from 8064
to MSM8996.

CRs-Fixed: 998927
Change-Id: I4baaa5a8b93cade64b0064acdc63b3b4ab7765e7
Signed-off-by: Shiju Mathew <shijum@codeaurora.org>
This commit is contained in:
Shiju Mathew 2016-03-31 17:27:34 -04:00 committed by Gerrit - the friendly Code Review server
parent 481c212aa7
commit 751f9ac72e
6 changed files with 201 additions and 49 deletions

View file

@ -99,6 +99,8 @@ int msm_ba_s_priority(void *instance, enum v4l2_priority prio)
struct msm_ba_input *ba_input = NULL;
int rc = 0;
dprintk(BA_DBG, "Enter %s, prio: %d", __func__, prio);
if (!inst)
return -EINVAL;
@ -174,15 +176,23 @@ int msm_ba_g_input(void *instance, unsigned int *index)
if (!inst || !index)
return -EINVAL;
/* First find current input */
ba_input = msm_ba_find_input(inst->sd_input.index);
if (ba_input) {
if (ba_input->prio == V4L2_PRIORITY_RECORD &&
inst->input_prio != ba_input->prio) {
inst->sd_input.index++;
do {
/* First find current input */
ba_input = msm_ba_find_input(inst->sd_input.index);
if (ba_input) {
if (ba_input->input_user_type ==
BA_INPUT_USERTYPE_KERNEL) {
inst->sd_input.index++;
continue;
}
break;
}
}
*index = inst->sd_input.index;
} while (ba_input);
if (ba_input)
*index = inst->sd_input.index;
else
rc = -ENOENT;
return rc;
}
@ -223,6 +233,10 @@ int msm_ba_s_input(void *instance, unsigned int index)
ba_input->bridge_chip_ip);
rc_sig = v4l2_subdev_call(ba_input->sd,
video, s_stream, 0);
if (rc_sig)
dprintk(BA_ERR,
"%s: Error in stream off. rc_sig %d",
__func__, rc_sig);
}
} else {
dprintk(BA_WARN, "Sd %d in use", ba_input->ba_out);
@ -252,7 +266,6 @@ int msm_ba_s_input(void *instance, unsigned int index)
.id = 0,
.type = V4L2_EVENT_MSM_BA_SIGNAL_IN_LOCK};
int *ptr = (int *)sd_event.u.data;
ptr[0] = index;
ptr[1] = ba_input->signal_status;
msm_ba_queue_v4l2_event(inst, &sd_event);
@ -311,7 +324,6 @@ int msm_ba_s_output(void *instance, unsigned int index)
dprintk(BA_ERR, "No sd registered");
return -EINVAL;
}
ba_input->ba_node_addr = index;
ba_input->ba_out = index;
inst->sd_output.index = index;
inst->sd = ba_input->sd;
@ -380,9 +392,11 @@ int msm_ba_g_fmt(void *instance, struct v4l2_format *f)
inst->sd_input.std = new_std;
} else {
rc = v4l2_subdev_call(sd, video, g_dv_timings, &sd_dv_timings);
if (rc)
if (rc) {
dprintk(BA_ERR, "g_dv_timings failed %d for sd: %s",
rc, sd->name);
return -EINVAL;
}
}
rc = v4l2_subdev_call(sd, video, g_mbus_fmt, &sd_mbus_fmt);
@ -503,6 +517,113 @@ int msm_ba_streamoff(void *instance, enum v4l2_buf_type i)
}
EXPORT_SYMBOL(msm_ba_streamoff);
long msm_ba_private_ioctl(void *instance, int cmd, void *arg)
{
long rc = 0;
struct msm_ba_inst *inst = instance;
struct v4l2_subdev *sd = NULL;
int *s_ioctl = arg;
dprintk(BA_DBG, "Enter %s with command: 0x%x", __func__, cmd);
if (!inst)
return -EINVAL;
switch (cmd) {
case VIDIOC_HDMI_RX_CEC_S_LOGICAL: {
dprintk(BA_DBG, "VIDIOC_HDMI_RX_CEC_S_LOGICAL");
sd = inst->sd;
if (!sd) {
dprintk(BA_ERR, "No sd registered");
return -EINVAL;
}
if (s_ioctl) {
rc = v4l2_subdev_call(sd, core, ioctl, cmd, s_ioctl);
if (rc)
dprintk(BA_ERR, "%s failed: %ld on cmd: 0x%x",
__func__, rc, cmd);
} else {
dprintk(BA_ERR, "%s: NULL argument provided", __func__);
rc = -EINVAL;
}
}
break;
case VIDIOC_HDMI_RX_CEC_CLEAR_LOGICAL: {
dprintk(BA_DBG, "VIDIOC_HDMI_RX_CEC_CLEAR_LOGICAL");
sd = inst->sd;
if (!sd) {
dprintk(BA_ERR, "No sd registered");
return -EINVAL;
}
rc = v4l2_subdev_call(sd, core, ioctl, cmd, s_ioctl);
if (rc)
dprintk(BA_ERR, "%s failed: %ld on cmd: 0x%x",
__func__, rc, cmd);
}
break;
case VIDIOC_HDMI_RX_CEC_G_PHYSICAL: {
dprintk(BA_DBG, "VIDIOC_HDMI_RX_CEC_G_PHYSICAL");
sd = inst->sd;
if (!sd) {
dprintk(BA_ERR, "No sd registered");
return -EINVAL;
}
if (s_ioctl) {
rc = v4l2_subdev_call(sd, core, ioctl, cmd, s_ioctl);
if (rc)
dprintk(BA_ERR, "%s failed: %ld on cmd: 0x%x",
__func__, rc, cmd);
} else {
dprintk(BA_ERR, "%s: NULL argument provided", __func__);
rc = -EINVAL;
}
}
break;
case VIDIOC_HDMI_RX_CEC_G_CONNECTED: {
dprintk(BA_DBG, "VIDIOC_HDMI_RX_CEC_G_CONNECTED");
sd = inst->sd;
if (!sd) {
dprintk(BA_ERR, "No sd registered");
return -EINVAL;
}
if (s_ioctl) {
rc = v4l2_subdev_call(sd, core, ioctl, cmd, s_ioctl);
if (rc)
dprintk(BA_ERR, "%s failed: %ld on cmd: 0x%x",
__func__, rc, cmd);
} else {
dprintk(BA_ERR, "%s: NULL argument provided", __func__);
rc = -EINVAL;
}
}
break;
case VIDIOC_HDMI_RX_CEC_S_ENABLE: {
dprintk(BA_DBG, "VIDIOC_HDMI_RX_CEC_S_ENABLE");
sd = inst->sd;
if (!sd) {
dprintk(BA_ERR, "No sd registered");
return -EINVAL;
}
if (s_ioctl) {
rc = v4l2_subdev_call(sd, core, ioctl, cmd, s_ioctl);
if (rc)
dprintk(BA_ERR, "%s failed: %ld on cmd: 0x%x",
__func__, rc, cmd);
} else {
dprintk(BA_ERR, "%s: NULL argument provided", __func__);
rc = -EINVAL;
}
}
break;
default:
dprintk(BA_WARN, "Not a typewriter! Command: 0x%x", cmd);
rc = -ENOTTY;
break;
}
return rc;
}
EXPORT_SYMBOL(msm_ba_private_ioctl);
int msm_ba_save_restore_input(void *instance, enum msm_ba_save_restore_ip sr)
{
struct msm_ba_inst *inst = instance;
@ -535,7 +656,10 @@ int msm_ba_save_restore_input(void *instance, enum msm_ba_save_restore_ip sr)
rc = msm_ba_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
} else if (sr == BA_SR_SAVE_IP) {
ba_input = msm_ba_find_input(inst->sd_input.index);
if (ba_input && ba_input->ba_out_in_use) {
if (ba_input == NULL) {
dprintk(BA_ERR, "Could not find input %d",
inst->sd_input.index);
} else if (ba_input->ba_out_in_use) {
inst->restore = 1;
inst->saved_input =
msm_ba_find_ip_in_use_from_sd(inst->sd);
@ -547,9 +671,6 @@ int msm_ba_save_restore_input(void *instance, enum msm_ba_save_restore_ip sr)
inst->saved_input);
rc = -EBUSY;
}
if (!ba_input)
dprintk(BA_WARN, "Couldn't find input idx %d to save",
inst->sd_input.index);
} else {
dprintk(BA_DBG, "Nothing to do in save and restore");
}

View file

@ -20,15 +20,22 @@
#include "msm_ba_common.h"
struct msm_ba_input_config msm_ba_inp_cfg[] = {
/* type, index, name, adv inp, dev id, sd name, signal status */
{BA_INPUT_CVBS, 0, "CVBS-0", BA_IP_CVBS_0, 0, "adv7180", 1},
/* type, index, name, adv inp, dev id, sd name, dev node,
* input user type
*/
{BA_INPUT_CVBS, 0, "CVBS-0", BA_IP_CVBS_0, 0, "adv7180", -1,
BA_INPUT_USERTYPE_KERNEL},
#ifdef CONFIG_MSM_S_PLATFORM
{BA_INPUT_CVBS, 1, "CVBS-1", BA_IP_CVBS_0, 0, "adv7180", 1},
{BA_INPUT_CVBS, 1, "CVBS-1", BA_IP_CVBS_0, 0, "adv7180", 0,
BA_INPUT_USERTYPE_USER},
#else
{BA_INPUT_CVBS, 1, "CVBS-1", BA_IP_CVBS_0, 1, "adv7180", 1},
{BA_INPUT_CVBS, 2, "CVBS-2", BA_IP_CVBS_1, 1, "adv7180", 1},
{BA_INPUT_CVBS, 1, "CVBS-1", BA_IP_CVBS_0, 1, "adv7180", 0,
BA_INPUT_USERTYPE_USER},
{BA_INPUT_CVBS, 2, "CVBS-2", BA_IP_CVBS_1, 1, "adv7180", 0,
BA_INPUT_USERTYPE_USER},
#endif
{BA_INPUT_HDMI, 1, "HDMI-1", BA_IP_HDMI_1, 2, "adv7481", 1},
{BA_INPUT_HDMI, 1, "HDMI-1", BA_IP_HDMI_1, 2, "adv7481", 2,
BA_INPUT_USERTYPE_USER},
};
static struct msm_ba_ctrl msm_ba_ctrls[] = {
@ -82,7 +89,7 @@ struct msm_ba_dev *get_ba_dev(void)
}
void msm_ba_queue_v4l2_event(struct msm_ba_inst *inst,
const struct v4l2_event *sd_event)
struct v4l2_event *sd_event)
{
v4l2_event_queue_fh(&inst->event_handler, sd_event);
wake_up(&inst->kernel_event_queue);
@ -91,6 +98,10 @@ void msm_ba_queue_v4l2_event(struct msm_ba_inst *inst,
static void msm_ba_print_event(struct v4l2_event *sd_event)
{
switch (sd_event->type) {
case V4L2_EVENT_MSM_BA_PORT_SETTINGS_CHANGED:
dprintk(BA_DBG, "Port settings changed for ip_idx %d",
((int *)sd_event->u.data)[0]);
break;
case V4L2_EVENT_MSM_BA_SIGNAL_IN_LOCK:
dprintk(BA_DBG, "Signal in lock for ip_idx %d",
((int *)sd_event->u.data)[0]);
@ -112,6 +123,11 @@ static void msm_ba_print_event(struct v4l2_event *sd_event)
case V4L2_EVENT_MSM_BA_CP:
dprintk(BA_DBG, "Content protection detected!");
break;
case V4L2_EVENT_MSM_BA_CABLE_DETECT:
dprintk(BA_DBG, "Cable detected: %d on ip_idx %d",
((int *)sd_event->u.data)[1],
((int *)sd_event->u.data)[0]);
break;
case V4L2_EVENT_MSM_BA_ERROR:
dprintk(BA_DBG, "Subdev error %d!",
((int *)sd_event->u.data)[1]);
@ -126,27 +142,18 @@ static void msm_ba_signal_sessions_event(struct v4l2_event *sd_event)
{
struct msm_ba_inst *inst = NULL;
struct msm_ba_dev *dev_ctxt = NULL;
unsigned int *ptr;
uintptr_t arg;
const struct v4l2_event event = {
.id = 0,
.type = sd_event->type,
.u = sd_event->u};
int *ptr;
msm_ba_print_event(sd_event);
dev_ctxt = get_ba_dev();
ptr = (unsigned int *)sd_event->u.data;
ptr = (int *)sd_event->u.data;
list_for_each_entry(inst, &(dev_ctxt->instances), list) {
if (inst->ext_ops && inst->ext_ops->msm_ba_cb) {
arg = ptr[1];
if (inst->ext_ops && inst->ext_ops->msm_ba_cb)
inst->ext_ops->msm_ba_cb(
inst, sd_event->id, (void *)arg);
} else {
msm_ba_queue_v4l2_event(inst, &event);
}
inst, sd_event->id, (void *)&ptr[1]);
else
msm_ba_queue_v4l2_event(inst, sd_event);
}
}
@ -224,8 +231,11 @@ void msm_ba_add_inputs(struct v4l2_subdev *sd)
sizeof(input->name));
input->bridge_chip_ip = msm_ba_inp_cfg[i].ba_ip;
input->ba_out = msm_ba_inp_cfg[i].ba_out;
input->ba_node_addr = msm_ba_inp_cfg[i].ba_node;
input->ba_ip_idx = i;
input->prio = V4L2_PRIORITY_DEFAULT;
input->input_user_type =
msm_ba_inp_cfg[i].input_user_type;
input->sd = sd;
rc = v4l2_subdev_call(
sd, video, g_input_status, &status);
@ -582,7 +592,6 @@ int msm_ba_ctrl_init(struct msm_ba_inst *inst)
}
for (; idx < BA_NUM_CTRLS; idx++) {
struct v4l2_ctrl *ctrl = NULL;
if (BA_IS_PRIV_CTRL(msm_ba_ctrls[idx].id)) {
/* add private control */
ctrl_cfg.def = msm_ba_ctrls[idx].default_value;
@ -620,12 +629,9 @@ int msm_ba_ctrl_init(struct msm_ba_inst *inst)
}
}
switch (msm_ba_ctrls[idx].id) {
case MSM_BA_PRIV_SD_NODE_ADDR:
case MSM_BA_PRIV_FPS:
if (ctrl)
ctrl->flags |= msm_ba_ctrls[idx].flags;
break;
if (!ctrl) {
dprintk(BA_ERR, "%s - invalid ctrl", __func__);
return -EINVAL;
}
rc = inst->ctrl_handler.error;
@ -637,6 +643,13 @@ int msm_ba_ctrl_init(struct msm_ba_inst *inst)
return rc;
}
switch (msm_ba_ctrls[idx].id) {
case MSM_BA_PRIV_SD_NODE_ADDR:
case MSM_BA_PRIV_FPS:
ctrl->flags |= msm_ba_ctrls[idx].flags;
break;
}
inst->ctrls[idx] = ctrl;
}

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-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
@ -22,7 +22,7 @@
struct msm_ba_dev *get_ba_dev(void);
void msm_ba_queue_v4l2_event(struct msm_ba_inst *inst,
const struct v4l2_event *sd_event);
struct v4l2_event *sd_event);
struct v4l2_subdev *msm_ba_sd_find(const char *name);
void msm_ba_add_inputs(struct v4l2_subdev *sd);
void msm_ba_del_inputs(struct v4l2_subdev *sd);

View file

@ -44,6 +44,7 @@
enum ba_dev_state {
BA_DEV_UNINIT = 0,
BA_DEV_LOADED,
BA_DEV_INIT,
BA_DEV_INIT_DONE,
BA_DEV_INVALID
@ -111,6 +112,12 @@ enum msm_ba_ip_type {
BA_INPUT_MAX = 0xffffffff
};
enum msm_ba_input_usr_type {
BA_INPUT_USERTYPE_KERNEL = 0,
BA_INPUT_USERTYPE_USER,
BA_INPUT_USERTYPE_MAX = 0xffffffff
};
struct msm_ba_input_config {
enum msm_ba_ip_type inputType;
unsigned int index;
@ -118,7 +125,8 @@ struct msm_ba_input_config {
int ba_ip;
int ba_out;
const char *sd_name;
int signal_status;
int ba_node;
enum msm_ba_input_usr_type input_user_type;
};
struct msm_ba_sd_event {
@ -140,6 +148,7 @@ struct msm_ba_input {
int in_use;
int ba_out_in_use;
enum v4l2_priority prio;
enum msm_ba_input_usr_type input_user_type;
};
struct msm_ba_dev {

View file

@ -436,7 +436,7 @@ static int msm_ba_remove(struct platform_device *pdev)
dprintk(BA_INFO, "Enter %s", __func__);
if (!pdev) {
dprintk(BA_ERR, "%s invalid input %p", __func__, pdev);
dprintk(BA_ERR, "%s invalid input 0x%p", __func__, pdev);
rc = -EINVAL;
} else {
dev_ctxt = pdev->dev.platform_data;

View file

@ -2207,8 +2207,10 @@ struct v4l2_streamparm {
(V4L2_EVENT_MSM_BA_START + 8)
#define V4L2_EVENT_MSM_BA_CP \
(V4L2_EVENT_MSM_BA_START + 9)
#define V4L2_EVENT_MSM_BA_ERROR \
#define V4L2_EVENT_MSM_BA_CABLE_DETECT \
(V4L2_EVENT_MSM_BA_START + 10)
#define V4L2_EVENT_MSM_BA_ERROR \
(V4L2_EVENT_MSM_BA_START + 11)
/* Payload for V4L2_EVENT_VSYNC */
struct v4l2_event_vsync {
@ -2465,4 +2467,11 @@ struct v4l2_create_buffers {
#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
/* HDMI rx provide ioctls */
#define VIDIOC_HDMI_RX_CEC_S_LOGICAL _IOW('V', BASE_VIDIOC_PRIVATE + 0, int)
#define VIDIOC_HDMI_RX_CEC_CLEAR_LOGICAL _IO('V', BASE_VIDIOC_PRIVATE + 1)
#define VIDIOC_HDMI_RX_CEC_G_PHYSICAL _IOR('V', BASE_VIDIOC_PRIVATE + 2, int)
#define VIDIOC_HDMI_RX_CEC_G_CONNECTED _IOR('V', BASE_VIDIOC_PRIVATE + 3, int)
#define VIDIOC_HDMI_RX_CEC_S_ENABLE _IOR('V', BASE_VIDIOC_PRIVATE + 4, int)
#endif /* _UAPI__LINUX_VIDEODEV2_H */