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; struct msm_ba_input *ba_input = NULL;
int rc = 0; int rc = 0;
dprintk(BA_DBG, "Enter %s, prio: %d", __func__, prio);
if (!inst) if (!inst)
return -EINVAL; return -EINVAL;
@ -174,15 +176,23 @@ int msm_ba_g_input(void *instance, unsigned int *index)
if (!inst || !index) if (!inst || !index)
return -EINVAL; return -EINVAL;
do {
/* First find current input */ /* First find current input */
ba_input = msm_ba_find_input(inst->sd_input.index); ba_input = msm_ba_find_input(inst->sd_input.index);
if (ba_input) { if (ba_input) {
if (ba_input->prio == V4L2_PRIORITY_RECORD && if (ba_input->input_user_type ==
inst->input_prio != ba_input->prio) { BA_INPUT_USERTYPE_KERNEL) {
inst->sd_input.index++; inst->sd_input.index++;
continue;
} }
break;
} }
} while (ba_input);
if (ba_input)
*index = inst->sd_input.index; *index = inst->sd_input.index;
else
rc = -ENOENT;
return rc; return rc;
} }
@ -223,6 +233,10 @@ int msm_ba_s_input(void *instance, unsigned int index)
ba_input->bridge_chip_ip); ba_input->bridge_chip_ip);
rc_sig = v4l2_subdev_call(ba_input->sd, rc_sig = v4l2_subdev_call(ba_input->sd,
video, s_stream, 0); video, s_stream, 0);
if (rc_sig)
dprintk(BA_ERR,
"%s: Error in stream off. rc_sig %d",
__func__, rc_sig);
} }
} else { } else {
dprintk(BA_WARN, "Sd %d in use", ba_input->ba_out); 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, .id = 0,
.type = V4L2_EVENT_MSM_BA_SIGNAL_IN_LOCK}; .type = V4L2_EVENT_MSM_BA_SIGNAL_IN_LOCK};
int *ptr = (int *)sd_event.u.data; int *ptr = (int *)sd_event.u.data;
ptr[0] = index; ptr[0] = index;
ptr[1] = ba_input->signal_status; ptr[1] = ba_input->signal_status;
msm_ba_queue_v4l2_event(inst, &sd_event); 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"); dprintk(BA_ERR, "No sd registered");
return -EINVAL; return -EINVAL;
} }
ba_input->ba_node_addr = index;
ba_input->ba_out = index; ba_input->ba_out = index;
inst->sd_output.index = index; inst->sd_output.index = index;
inst->sd = ba_input->sd; 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; inst->sd_input.std = new_std;
} else { } else {
rc = v4l2_subdev_call(sd, video, g_dv_timings, &sd_dv_timings); 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", dprintk(BA_ERR, "g_dv_timings failed %d for sd: %s",
rc, sd->name); rc, sd->name);
return -EINVAL;
}
} }
rc = v4l2_subdev_call(sd, video, g_mbus_fmt, &sd_mbus_fmt); 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); 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) int msm_ba_save_restore_input(void *instance, enum msm_ba_save_restore_ip sr)
{ {
struct msm_ba_inst *inst = instance; 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); rc = msm_ba_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
} else if (sr == BA_SR_SAVE_IP) { } else if (sr == BA_SR_SAVE_IP) {
ba_input = msm_ba_find_input(inst->sd_input.index); 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->restore = 1;
inst->saved_input = inst->saved_input =
msm_ba_find_ip_in_use_from_sd(inst->sd); 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); inst->saved_input);
rc = -EBUSY; rc = -EBUSY;
} }
if (!ba_input)
dprintk(BA_WARN, "Couldn't find input idx %d to save",
inst->sd_input.index);
} else { } else {
dprintk(BA_DBG, "Nothing to do in save and restore"); dprintk(BA_DBG, "Nothing to do in save and restore");
} }

View file

@ -20,15 +20,22 @@
#include "msm_ba_common.h" #include "msm_ba_common.h"
struct msm_ba_input_config msm_ba_inp_cfg[] = { struct msm_ba_input_config msm_ba_inp_cfg[] = {
/* type, index, name, adv inp, dev id, sd name, signal status */ /* type, index, name, adv inp, dev id, sd name, dev node,
{BA_INPUT_CVBS, 0, "CVBS-0", BA_IP_CVBS_0, 0, "adv7180", 1}, * 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 #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 #else
{BA_INPUT_CVBS, 1, "CVBS-1", BA_IP_CVBS_0, 1, "adv7180", 1}, {BA_INPUT_CVBS, 1, "CVBS-1", BA_IP_CVBS_0, 1, "adv7180", 0,
{BA_INPUT_CVBS, 2, "CVBS-2", BA_IP_CVBS_1, 1, "adv7180", 1}, BA_INPUT_USERTYPE_USER},
{BA_INPUT_CVBS, 2, "CVBS-2", BA_IP_CVBS_1, 1, "adv7180", 0,
BA_INPUT_USERTYPE_USER},
#endif #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[] = { 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, 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); v4l2_event_queue_fh(&inst->event_handler, sd_event);
wake_up(&inst->kernel_event_queue); 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) static void msm_ba_print_event(struct v4l2_event *sd_event)
{ {
switch (sd_event->type) { 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: case V4L2_EVENT_MSM_BA_SIGNAL_IN_LOCK:
dprintk(BA_DBG, "Signal in lock for ip_idx %d", dprintk(BA_DBG, "Signal in lock for ip_idx %d",
((int *)sd_event->u.data)[0]); ((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: case V4L2_EVENT_MSM_BA_CP:
dprintk(BA_DBG, "Content protection detected!"); dprintk(BA_DBG, "Content protection detected!");
break; 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: case V4L2_EVENT_MSM_BA_ERROR:
dprintk(BA_DBG, "Subdev error %d!", dprintk(BA_DBG, "Subdev error %d!",
((int *)sd_event->u.data)[1]); ((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_inst *inst = NULL;
struct msm_ba_dev *dev_ctxt = NULL; struct msm_ba_dev *dev_ctxt = NULL;
unsigned int *ptr; int *ptr;
uintptr_t arg;
const struct v4l2_event event = {
.id = 0,
.type = sd_event->type,
.u = sd_event->u};
msm_ba_print_event(sd_event); msm_ba_print_event(sd_event);
dev_ctxt = get_ba_dev(); 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) { list_for_each_entry(inst, &(dev_ctxt->instances), list) {
if (inst->ext_ops && inst->ext_ops->msm_ba_cb) { if (inst->ext_ops && inst->ext_ops->msm_ba_cb)
arg = ptr[1];
inst->ext_ops->msm_ba_cb( inst->ext_ops->msm_ba_cb(
inst, sd_event->id, (void *)arg); inst, sd_event->id, (void *)&ptr[1]);
} else { else
msm_ba_queue_v4l2_event(inst, &event); msm_ba_queue_v4l2_event(inst, sd_event);
}
} }
} }
@ -224,8 +231,11 @@ void msm_ba_add_inputs(struct v4l2_subdev *sd)
sizeof(input->name)); sizeof(input->name));
input->bridge_chip_ip = msm_ba_inp_cfg[i].ba_ip; input->bridge_chip_ip = msm_ba_inp_cfg[i].ba_ip;
input->ba_out = msm_ba_inp_cfg[i].ba_out; 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->ba_ip_idx = i;
input->prio = V4L2_PRIORITY_DEFAULT; input->prio = V4L2_PRIORITY_DEFAULT;
input->input_user_type =
msm_ba_inp_cfg[i].input_user_type;
input->sd = sd; input->sd = sd;
rc = v4l2_subdev_call( rc = v4l2_subdev_call(
sd, video, g_input_status, &status); 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++) { for (; idx < BA_NUM_CTRLS; idx++) {
struct v4l2_ctrl *ctrl = NULL; struct v4l2_ctrl *ctrl = NULL;
if (BA_IS_PRIV_CTRL(msm_ba_ctrls[idx].id)) { if (BA_IS_PRIV_CTRL(msm_ba_ctrls[idx].id)) {
/* add private control */ /* add private control */
ctrl_cfg.def = msm_ba_ctrls[idx].default_value; 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) { if (!ctrl) {
case MSM_BA_PRIV_SD_NODE_ADDR: dprintk(BA_ERR, "%s - invalid ctrl", __func__);
case MSM_BA_PRIV_FPS: return -EINVAL;
if (ctrl)
ctrl->flags |= msm_ba_ctrls[idx].flags;
break;
} }
rc = inst->ctrl_handler.error; rc = inst->ctrl_handler.error;
@ -637,6 +643,13 @@ int msm_ba_ctrl_init(struct msm_ba_inst *inst)
return rc; 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; 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 * 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 * 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); struct msm_ba_dev *get_ba_dev(void);
void msm_ba_queue_v4l2_event(struct msm_ba_inst *inst, 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); struct v4l2_subdev *msm_ba_sd_find(const char *name);
void msm_ba_add_inputs(struct v4l2_subdev *sd); void msm_ba_add_inputs(struct v4l2_subdev *sd);
void msm_ba_del_inputs(struct v4l2_subdev *sd); void msm_ba_del_inputs(struct v4l2_subdev *sd);

View file

@ -44,6 +44,7 @@
enum ba_dev_state { enum ba_dev_state {
BA_DEV_UNINIT = 0, BA_DEV_UNINIT = 0,
BA_DEV_LOADED,
BA_DEV_INIT, BA_DEV_INIT,
BA_DEV_INIT_DONE, BA_DEV_INIT_DONE,
BA_DEV_INVALID BA_DEV_INVALID
@ -111,6 +112,12 @@ enum msm_ba_ip_type {
BA_INPUT_MAX = 0xffffffff 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 { struct msm_ba_input_config {
enum msm_ba_ip_type inputType; enum msm_ba_ip_type inputType;
unsigned int index; unsigned int index;
@ -118,7 +125,8 @@ struct msm_ba_input_config {
int ba_ip; int ba_ip;
int ba_out; int ba_out;
const char *sd_name; const char *sd_name;
int signal_status; int ba_node;
enum msm_ba_input_usr_type input_user_type;
}; };
struct msm_ba_sd_event { struct msm_ba_sd_event {
@ -140,6 +148,7 @@ struct msm_ba_input {
int in_use; int in_use;
int ba_out_in_use; int ba_out_in_use;
enum v4l2_priority prio; enum v4l2_priority prio;
enum msm_ba_input_usr_type input_user_type;
}; };
struct msm_ba_dev { 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__); dprintk(BA_INFO, "Enter %s", __func__);
if (!pdev) { if (!pdev) {
dprintk(BA_ERR, "%s invalid input %p", __func__, pdev); dprintk(BA_ERR, "%s invalid input 0x%p", __func__, pdev);
rc = -EINVAL; rc = -EINVAL;
} else { } else {
dev_ctxt = pdev->dev.platform_data; dev_ctxt = pdev->dev.platform_data;

View file

@ -2207,8 +2207,10 @@ struct v4l2_streamparm {
(V4L2_EVENT_MSM_BA_START + 8) (V4L2_EVENT_MSM_BA_START + 8)
#define V4L2_EVENT_MSM_BA_CP \ #define V4L2_EVENT_MSM_BA_CP \
(V4L2_EVENT_MSM_BA_START + 9) (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) (V4L2_EVENT_MSM_BA_START + 10)
#define V4L2_EVENT_MSM_BA_ERROR \
(V4L2_EVENT_MSM_BA_START + 11)
/* Payload for V4L2_EVENT_VSYNC */ /* Payload for V4L2_EVENT_VSYNC */
struct v4l2_event_vsync { struct v4l2_event_vsync {
@ -2465,4 +2467,11 @@ struct v4l2_create_buffers {
#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ #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 */ #endif /* _UAPI__LINUX_VIDEODEV2_H */