Skip to content

Commit

Permalink
media: adv748x: Implement .get_frame_desc()
Browse files Browse the repository at this point in the history
Implement the get_frame_desc subdev pad operation.

Implement the get_frame_desc pad operation to allow retrieving the
stream configuration of the adv748x csi2 subdevice.

Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
  • Loading branch information
Jacopo Mondi authored and intel-lab-lkp committed Dec 16, 2021
1 parent 90158bf commit 3baa5f5
Showing 1 changed file with 93 additions and 0 deletions.
93 changes: 93 additions & 0 deletions drivers/media/i2c/adv748x/adv748x-csi2.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,50 @@

#include "adv748x.h"

/* Describes a format bit depth and CSI-2 defined Data Type. */
struct adv748x_csi2_format_info {
u8 dt;
u8 bpp;
};

static int adv748x_csi2_get_format_info(struct adv748x_csi2 *tx,
u32 mbus_code,
struct adv748x_csi2_format_info *fmt)
{
switch (mbus_code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
case MEDIA_BUS_FMT_YUYV8_2X8:
fmt->dt = 0x1e;
fmt->bpp = 16;
break;
case MEDIA_BUS_FMT_YUYV10_2X10:
case MEDIA_BUS_FMT_YUYV10_1X20:
fmt->dt = 0x1f;
fmt->bpp = 20;
break;
case MEDIA_BUS_FMT_RGB565_1X16:
case MEDIA_BUS_FMT_RGB565_2X8_LE:
case MEDIA_BUS_FMT_RGB565_2X8_BE:
fmt->dt = 0x22;
fmt->bpp = 16;
break;
case MEDIA_BUS_FMT_RGB666_1X18:
fmt->dt = 0x23;
fmt->bpp = 18;
break;
case MEDIA_BUS_FMT_RGB888_1X24:
fmt->dt = 0x24;
fmt->bpp = 24;
break;
default:
dev_err(tx->state->dev,
"Unsupported media bus code: %u\n", mbus_code);
return -EINVAL;
}

return 0;
}

int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx, unsigned int vc)
{
return tx_write(tx, ADV748X_CSI_VC_REF, vc << ADV748X_CSI_VC_REF_SHIFT);
Expand Down Expand Up @@ -248,11 +292,60 @@ static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad
return 0;
}

static int adv748x_csi2_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_mbus_frame_desc *fd)
{
struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
struct adv748x_csi2_format_info info = {};
struct v4l2_mbus_frame_desc_entry *entry;
struct v4l2_subdev_route *route;
struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *fmt;
int ret;

if (pad != ADV748X_CSI2_SOURCE)
return -EINVAL;

state = v4l2_subdev_lock_active_state(sd);

/* A single route is available. */
route = &state->routing.routes[0];
fmt = v4l2_state_get_stream_format(state, pad, route->source_stream);
if (!fmt) {
ret = -EINVAL;
goto out;
}

ret = adv748x_csi2_get_format_info(tx, fmt->code, &info);
if (ret)
goto out;

memset(fd, 0, sizeof(*fd));

/* A single stream is available. */
fd->num_entries = 1;
fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;

entry = &fd->entry[0];
entry->stream = 0;
entry->flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
entry->length = fmt->width * fmt->height * info.bpp / 8;
entry->pixelcode = fmt->code;
entry->bus.csi2.vc = route->source_stream;
entry->bus.csi2.dt = info.dt;

out:
v4l2_subdev_unlock_state(state);

return ret;
}

static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
.init_cfg = adv748x_csi2_init_cfg,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = adv748x_csi2_set_format,
.get_mbus_config = adv748x_csi2_get_mbus_config,
.get_frame_desc = adv748x_csi2_get_frame_desc,
};

/* -----------------------------------------------------------------------------
Expand Down

0 comments on commit 3baa5f5

Please sign in to comment.