media: ivsc: csi: Obtain link frequency from the media pad
Support the use of the media pad for obtaining the link frequency. Similarly, call the v4l2_get_link_freq() on the media pad, not on the remote's control handler. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
This commit is contained in:
parent
55a163e6d9
commit
56f697e3cd
@ -35,8 +35,6 @@
|
||||
|
||||
#define MEI_CSI_ENTITY_NAME "Intel IVSC CSI"
|
||||
|
||||
#define MEI_CSI_LINK_FREQ_400MHZ 400000000ULL
|
||||
|
||||
/* the 5s used here is based on experiment */
|
||||
#define CSI_CMD_TIMEOUT (5 * HZ)
|
||||
/* to setup CSI-2 link an extra delay needed and determined experimentally */
|
||||
@ -121,14 +119,13 @@ struct mei_csi {
|
||||
struct mutex lock;
|
||||
|
||||
struct v4l2_subdev subdev;
|
||||
struct v4l2_subdev *remote;
|
||||
struct media_pad *remote;
|
||||
struct v4l2_async_notifier notifier;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
struct v4l2_ctrl *freq_ctrl;
|
||||
struct v4l2_ctrl *privacy_ctrl;
|
||||
/* lock for v4l2 controls */
|
||||
struct mutex ctrl_lock;
|
||||
unsigned int remote_pad;
|
||||
/* start streaming or not */
|
||||
int streaming;
|
||||
|
||||
@ -147,10 +144,6 @@ static const struct v4l2_mbus_framefmt mei_csi_format_mbus_default = {
|
||||
.field = V4L2_FIELD_NONE,
|
||||
};
|
||||
|
||||
static s64 link_freq_menu_items[] = {
|
||||
MEI_CSI_LINK_FREQ_400MHZ
|
||||
};
|
||||
|
||||
static inline struct mei_csi *notifier_to_csi(struct v4l2_async_notifier *n)
|
||||
{
|
||||
return container_of(n, struct mei_csi, notifier);
|
||||
@ -161,11 +154,6 @@ static inline struct mei_csi *sd_to_csi(struct v4l2_subdev *sd)
|
||||
return container_of(sd, struct mei_csi, subdev);
|
||||
}
|
||||
|
||||
static inline struct mei_csi *ctrl_to_csi(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
return container_of(ctrl->handler, struct mei_csi, ctrl_handler);
|
||||
}
|
||||
|
||||
/* send a command to firmware and mutex must be held by caller */
|
||||
static int mei_csi_send(struct mei_csi *csi, u8 *buf, size_t len)
|
||||
{
|
||||
@ -286,11 +274,13 @@ static void mei_csi_rx(struct mei_cl_device *cldev)
|
||||
static int mei_csi_set_stream(struct v4l2_subdev *sd, int enable)
|
||||
{
|
||||
struct mei_csi *csi = sd_to_csi(sd);
|
||||
struct v4l2_subdev *remote_sd =
|
||||
media_entity_to_v4l2_subdev(csi->remote->entity);
|
||||
s64 freq;
|
||||
int ret;
|
||||
|
||||
if (enable && csi->streaming == 0) {
|
||||
freq = v4l2_get_link_freq(csi->remote->ctrl_handler, 0, 0);
|
||||
freq = v4l2_get_link_freq(csi->remote, 0, 0);
|
||||
if (freq < 0) {
|
||||
dev_err(&csi->cldev->dev,
|
||||
"error %lld, invalid link_freq\n", freq);
|
||||
@ -309,11 +299,11 @@ static int mei_csi_set_stream(struct v4l2_subdev *sd, int enable)
|
||||
if (ret < 0)
|
||||
goto err_switch;
|
||||
|
||||
ret = v4l2_subdev_call(csi->remote, video, s_stream, 1);
|
||||
ret = v4l2_subdev_call(remote_sd, video, s_stream, 1);
|
||||
if (ret)
|
||||
goto err_switch;
|
||||
} else if (!enable && csi->streaming == 1) {
|
||||
v4l2_subdev_call(csi->remote, video, s_stream, 0);
|
||||
v4l2_subdev_call(remote_sd, video, s_stream, 0);
|
||||
|
||||
/* switch CSI-2 link to IVSC */
|
||||
ret = csi_set_link_owner(csi, CSI_LINK_IVSC);
|
||||
@ -470,34 +460,30 @@ static int mei_csi_set_fmt(struct v4l2_subdev *sd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mei_csi_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
||||
static int mei_csi_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
|
||||
struct v4l2_mbus_config *mbus_config)
|
||||
{
|
||||
struct mei_csi *csi = ctrl_to_csi(ctrl);
|
||||
struct mei_csi *csi = sd_to_csi(sd);
|
||||
unsigned int i;
|
||||
s64 freq;
|
||||
|
||||
if (ctrl->id == V4L2_CID_LINK_FREQ) {
|
||||
if (!csi->remote)
|
||||
return -EINVAL;
|
||||
mbus_config->type = V4L2_MBUS_CSI2_DPHY;
|
||||
for (i = 0; i < V4L2_MBUS_CSI2_MAX_DATA_LANES; i++)
|
||||
mbus_config->bus.mipi_csi2.data_lanes[i] = i + 1;
|
||||
mbus_config->bus.mipi_csi2.num_data_lanes = csi->nr_of_lanes;
|
||||
|
||||
freq = v4l2_get_link_freq(csi->remote->ctrl_handler, 0, 0);
|
||||
if (freq < 0) {
|
||||
dev_err(&csi->cldev->dev,
|
||||
"error %lld, invalid link_freq\n", freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
link_freq_menu_items[0] = freq;
|
||||
ctrl->val = 0;
|
||||
|
||||
return 0;
|
||||
freq = v4l2_get_link_freq(csi->remote, 0, 0);
|
||||
if (freq < 0) {
|
||||
dev_err(&csi->cldev->dev,
|
||||
"error %lld, invalid link_freq\n", freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
csi->link_freq = freq;
|
||||
mbus_config->link_freq = freq;
|
||||
|
||||
static const struct v4l2_ctrl_ops mei_csi_ctrl_ops = {
|
||||
.g_volatile_ctrl = mei_csi_g_volatile_ctrl,
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_video_ops mei_csi_video_ops = {
|
||||
.s_stream = mei_csi_set_stream,
|
||||
@ -506,6 +492,7 @@ static const struct v4l2_subdev_video_ops mei_csi_video_ops = {
|
||||
static const struct v4l2_subdev_pad_ops mei_csi_pad_ops = {
|
||||
.get_fmt = v4l2_subdev_get_fmt,
|
||||
.set_fmt = mei_csi_set_fmt,
|
||||
.get_mbus_config = mei_csi_get_mbus_config,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_ops mei_csi_subdev_ops = {
|
||||
@ -533,8 +520,7 @@ static int mei_csi_notify_bound(struct v4l2_async_notifier *notifier,
|
||||
if (pad < 0)
|
||||
return pad;
|
||||
|
||||
csi->remote = subdev;
|
||||
csi->remote_pad = pad;
|
||||
csi->remote = &subdev->entity.pads[pad];
|
||||
|
||||
return media_create_pad_link(&subdev->entity, pad,
|
||||
&csi->subdev.entity, CSI_PAD_SINK,
|
||||
@ -558,28 +544,16 @@ static const struct v4l2_async_notifier_operations mei_csi_notify_ops = {
|
||||
|
||||
static int mei_csi_init_controls(struct mei_csi *csi)
|
||||
{
|
||||
u32 max;
|
||||
int ret;
|
||||
|
||||
mutex_init(&csi->ctrl_lock);
|
||||
|
||||
ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 2);
|
||||
ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
csi->ctrl_handler.lock = &csi->ctrl_lock;
|
||||
|
||||
max = ARRAY_SIZE(link_freq_menu_items) - 1;
|
||||
csi->freq_ctrl = v4l2_ctrl_new_int_menu(&csi->ctrl_handler,
|
||||
&mei_csi_ctrl_ops,
|
||||
V4L2_CID_LINK_FREQ,
|
||||
max,
|
||||
0,
|
||||
link_freq_menu_items);
|
||||
if (csi->freq_ctrl)
|
||||
csi->freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY |
|
||||
V4L2_CTRL_FLAG_VOLATILE;
|
||||
|
||||
csi->privacy_ctrl = v4l2_ctrl_new_std(&csi->ctrl_handler, NULL,
|
||||
V4L2_CID_PRIVACY, 0, 1, 1, 0);
|
||||
if (csi->privacy_ctrl)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user