diff options
Diffstat (limited to 'drivers/media/platform/ti/cal/cal-camerarx.c')
-rw-r--r-- | drivers/media/platform/ti/cal/cal-camerarx.c | 206 |
1 files changed, 79 insertions, 127 deletions
diff --git a/drivers/media/platform/ti/cal/cal-camerarx.c b/drivers/media/platform/ti/cal/cal-camerarx.c index 16ae52879a79..1a4273bbe752 100644 --- a/drivers/media/platform/ti/cal/cal-camerarx.c +++ b/drivers/media/platform/ti/cal/cal-camerarx.c @@ -50,10 +50,16 @@ static s64 cal_camerarx_get_ext_link_freq(struct cal_camerarx *phy) struct v4l2_mbus_config_mipi_csi2 *mipi_csi2 = &phy->endpoint.bus.mipi_csi2; u32 num_lanes = mipi_csi2->num_data_lanes; const struct cal_format_info *fmtinfo; + struct v4l2_subdev_state *state; + struct v4l2_mbus_framefmt *fmt; u32 bpp; s64 freq; - fmtinfo = cal_format_by_code(phy->formats[CAL_CAMERARX_PAD_SINK].code); + state = v4l2_subdev_get_locked_active_state(&phy->subdev); + + fmt = v4l2_subdev_get_pad_format(&phy->subdev, state, CAL_CAMERARX_PAD_SINK); + + fmtinfo = cal_format_by_code(fmt->code); if (!fmtinfo) return -EINVAL; @@ -583,33 +589,6 @@ done: return ret; } -int cal_camerarx_get_remote_frame_desc(struct cal_camerarx *phy, - struct v4l2_mbus_frame_desc *desc) -{ - struct media_pad *pad; - int ret; - - if (!phy->source) - return -EPIPE; - - pad = media_pad_remote_pad_first(&phy->pads[CAL_CAMERARX_PAD_SINK]); - if (!pad) - return -EPIPE; - - ret = v4l2_subdev_call(phy->source, pad, get_frame_desc, pad->index, - desc); - if (ret) - return ret; - - if (desc->type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) { - dev_err(phy->cal->dev, - "Frame descriptor does not describe CSI-2 link"); - return -EINVAL; - } - - return 0; -} - /* ------------------------------------------------------------------ * V4L2 Subdev Operations * ------------------------------------------------------------------ @@ -620,34 +599,20 @@ static inline struct cal_camerarx *to_cal_camerarx(struct v4l2_subdev *sd) return container_of(sd, struct cal_camerarx, subdev); } -static struct v4l2_mbus_framefmt * -cal_camerarx_get_pad_format(struct cal_camerarx *phy, - struct v4l2_subdev_state *state, - unsigned int pad, u32 which) -{ - switch (which) { - case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&phy->subdev, state, pad); - case V4L2_SUBDEV_FORMAT_ACTIVE: - return &phy->formats[pad]; - default: - return NULL; - } -} - static int cal_camerarx_sd_s_stream(struct v4l2_subdev *sd, int enable) { struct cal_camerarx *phy = to_cal_camerarx(sd); + struct v4l2_subdev_state *state; int ret = 0; - mutex_lock(&phy->mutex); + state = v4l2_subdev_lock_and_get_active_state(sd); if (enable) ret = cal_camerarx_start(phy); else cal_camerarx_stop(phy); - mutex_unlock(&phy->mutex); + v4l2_subdev_unlock_state(state); return ret; } @@ -657,62 +622,44 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_mbus_code_enum *code) { struct cal_camerarx *phy = to_cal_camerarx(sd); - int ret = 0; - - mutex_lock(&phy->mutex); /* No transcoding, source and sink codes must match. */ if (cal_rx_pad_is_source(code->pad)) { struct v4l2_mbus_framefmt *fmt; - if (code->index > 0) { - ret = -EINVAL; - goto out; - } + if (code->index > 0) + return -EINVAL; - fmt = cal_camerarx_get_pad_format(phy, state, - CAL_CAMERARX_PAD_SINK, - code->which); + fmt = v4l2_subdev_get_pad_format(&phy->subdev, state, + CAL_CAMERARX_PAD_SINK); code->code = fmt->code; } else { - if (code->index >= cal_num_formats) { - ret = -EINVAL; - goto out; - } + if (code->index >= cal_num_formats) + return -EINVAL; code->code = cal_formats[code->index].code; } -out: - mutex_unlock(&phy->mutex); - - return ret; + return 0; } static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_frame_size_enum *fse) { - struct cal_camerarx *phy = to_cal_camerarx(sd); const struct cal_format_info *fmtinfo; - int ret = 0; if (fse->index > 0) return -EINVAL; - mutex_lock(&phy->mutex); - /* No transcoding, source and sink formats must match. */ if (cal_rx_pad_is_source(fse->pad)) { struct v4l2_mbus_framefmt *fmt; - fmt = cal_camerarx_get_pad_format(phy, state, - CAL_CAMERARX_PAD_SINK, - fse->which); - if (fse->code != fmt->code) { - ret = -EINVAL; - goto out; - } + fmt = v4l2_subdev_get_pad_format(sd, state, + CAL_CAMERARX_PAD_SINK); + if (fse->code != fmt->code) + return -EINVAL; fse->min_width = fmt->width; fse->max_width = fmt->width; @@ -720,10 +667,8 @@ static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd, fse->max_height = fmt->height; } else { fmtinfo = cal_format_by_code(fse->code); - if (!fmtinfo) { - ret = -EINVAL; - goto out; - } + if (!fmtinfo) + return -EINVAL; fse->min_width = CAL_MIN_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8); fse->max_width = CAL_MAX_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8); @@ -731,27 +676,6 @@ static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd, fse->max_height = CAL_MAX_HEIGHT_LINES; } -out: - mutex_unlock(&phy->mutex); - - return ret; -} - -static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *state, - struct v4l2_subdev_format *format) -{ - struct cal_camerarx *phy = to_cal_camerarx(sd); - struct v4l2_mbus_framefmt *fmt; - - mutex_lock(&phy->mutex); - - fmt = cal_camerarx_get_pad_format(phy, state, format->pad, - format->which); - format->format = *fmt; - - mutex_unlock(&phy->mutex); - return 0; } @@ -759,14 +683,13 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_format *format) { - struct cal_camerarx *phy = to_cal_camerarx(sd); const struct cal_format_info *fmtinfo; struct v4l2_mbus_framefmt *fmt; unsigned int bpp; /* No transcoding, source and sink formats must match. */ if (cal_rx_pad_is_source(format->pad)) - return cal_camerarx_sd_get_fmt(sd, state, format); + return v4l2_subdev_get_fmt(sd, state, format); /* * Default to the first format if the requested media bus code isn't @@ -790,20 +713,13 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd, /* Store the format and propagate it to the source pad. */ - mutex_lock(&phy->mutex); - - fmt = cal_camerarx_get_pad_format(phy, state, - CAL_CAMERARX_PAD_SINK, - format->which); + fmt = v4l2_subdev_get_pad_format(sd, state, CAL_CAMERARX_PAD_SINK); *fmt = format->format; - fmt = cal_camerarx_get_pad_format(phy, state, - CAL_CAMERARX_PAD_FIRST_SOURCE, - format->which); + fmt = v4l2_subdev_get_pad_format(sd, state, + CAL_CAMERARX_PAD_FIRST_SOURCE); *fmt = format->format; - mutex_unlock(&phy->mutex); - return 0; } @@ -817,7 +733,7 @@ static int cal_camerarx_sd_init_cfg(struct v4l2_subdev *sd, .format = { .width = 640, .height = 480, - .code = MEDIA_BUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_1X16, .field = V4L2_FIELD_NONE, .colorspace = V4L2_COLORSPACE_SRGB, .ycbcr_enc = V4L2_YCBCR_ENC_601, @@ -829,6 +745,40 @@ static int cal_camerarx_sd_init_cfg(struct v4l2_subdev *sd, return cal_camerarx_sd_set_fmt(sd, state, &format); } +static int cal_camerarx_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_frame_desc *fd) +{ + struct cal_camerarx *phy = to_cal_camerarx(sd); + struct v4l2_mbus_frame_desc remote_desc; + const struct media_pad *remote_pad; + int ret; + + remote_pad = media_pad_remote_pad_first(&phy->pads[CAL_CAMERARX_PAD_SINK]); + if (!remote_pad) + return -EPIPE; + + ret = v4l2_subdev_call(phy->source, pad, get_frame_desc, + remote_pad->index, &remote_desc); + if (ret) + return ret; + + if (remote_desc.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) { + cal_err(phy->cal, + "Frame descriptor does not describe CSI-2 link"); + return -EINVAL; + } + + if (remote_desc.num_entries > 1) + cal_err(phy->cal, + "Multiple streams not supported in remote frame descriptor, using the first one\n"); + + fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2; + fd->num_entries = 1; + fd->entry[0] = remote_desc.entry[0]; + + return 0; +} + static const struct v4l2_subdev_video_ops cal_camerarx_video_ops = { .s_stream = cal_camerarx_sd_s_stream, }; @@ -837,8 +787,9 @@ static const struct v4l2_subdev_pad_ops cal_camerarx_pad_ops = { .init_cfg = cal_camerarx_sd_init_cfg, .enum_mbus_code = cal_camerarx_sd_enum_mbus_code, .enum_frame_size = cal_camerarx_sd_enum_frame_size, - .get_fmt = cal_camerarx_sd_get_fmt, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = cal_camerarx_sd_set_fmt, + .get_frame_desc = cal_camerarx_get_frame_desc, }; static const struct v4l2_subdev_ops cal_camerarx_subdev_ops = { @@ -864,7 +815,7 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, unsigned int i; int ret; - phy = kzalloc(sizeof(*phy), GFP_KERNEL); + phy = devm_kzalloc(cal->dev, sizeof(*phy), GFP_KERNEL); if (!phy) return ERR_PTR(-ENOMEM); @@ -872,7 +823,6 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, phy->instance = instance; spin_lock_init(&phy->vc_lock); - mutex_init(&phy->mutex); phy->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, (instance == 0) ? @@ -881,8 +831,7 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, phy->base = devm_ioremap_resource(cal->dev, phy->res); if (IS_ERR(phy->base)) { cal_err(cal, "failed to ioremap\n"); - ret = PTR_ERR(phy->base); - goto error; + return ERR_CAST(phy->base); } cal_dbg(1, cal, "ioresource %s at %pa - %pa\n", @@ -890,11 +839,11 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, ret = cal_camerarx_regmap_init(cal, phy); if (ret) - goto error; + return ERR_PTR(ret); ret = cal_camerarx_parse_dt(phy); if (ret) - goto error; + return ERR_PTR(ret); /* Initialize the V4L2 subdev and media entity. */ sd = &phy->subdev; @@ -911,21 +860,25 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(phy->pads), phy->pads); if (ret) - goto error; + goto err_node_put; - ret = cal_camerarx_sd_init_cfg(sd, NULL); + ret = v4l2_subdev_init_finalize(sd); if (ret) - goto error; + goto err_entity_cleanup; ret = v4l2_device_register_subdev(&cal->v4l2_dev, sd); if (ret) - goto error; + goto err_free_state; return phy; -error: +err_free_state: + v4l2_subdev_cleanup(sd); +err_entity_cleanup: media_entity_cleanup(&phy->subdev.entity); - kfree(phy); +err_node_put: + of_node_put(phy->source_ep_node); + of_node_put(phy->source_node); return ERR_PTR(ret); } @@ -935,9 +888,8 @@ void cal_camerarx_destroy(struct cal_camerarx *phy) return; v4l2_device_unregister_subdev(&phy->subdev); + v4l2_subdev_cleanup(&phy->subdev); media_entity_cleanup(&phy->subdev.entity); of_node_put(phy->source_ep_node); of_node_put(phy->source_node); - mutex_destroy(&phy->mutex); - kfree(phy); } |