Skip to content

Commit

Permalink
media: camss: vfe: Different format support on source pad
Browse files Browse the repository at this point in the history
Rework the format selection on the source pad. Make the format
on the source pad selectable amongst a list of formats. This
list can be different for each sink pad format.

Signed-off-by: Todor Tomov <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
  • Loading branch information
todortomov authored and mchehab committed Aug 2, 2018
1 parent cba3819 commit 07eeb34
Showing 1 changed file with 135 additions and 37 deletions.
172 changes: 135 additions & 37 deletions drivers/media/platform/qcom/camss/camss-vfe.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,131 @@ static u8 vfe_get_bpp(const struct vfe_format *formats,
return formats[0].bpp;
}

static u32 vfe_find_code(u32 *code, unsigned int n_code,
unsigned int index, u32 req_code)
{
int i;

if (!req_code && (index >= n_code))
return 0;

for (i = 0; i < n_code; i++)
if (req_code) {
if (req_code == code[i])
return req_code;
} else {
if (i == index)
return code[i];
}

return code[0];
}

static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
unsigned int index, u32 src_req_code)
{
struct vfe_device *vfe = to_vfe(line);

if (vfe->camss->version == CAMSS_8x16)
switch (sink_code) {
case MEDIA_BUS_FMT_YUYV8_2X8:
{
u32 src_code[] = {
MEDIA_BUS_FMT_YUYV8_2X8,
MEDIA_BUS_FMT_YUYV8_1_5X8,
};

return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
case MEDIA_BUS_FMT_YVYU8_2X8:
{
u32 src_code[] = {
MEDIA_BUS_FMT_YVYU8_2X8,
MEDIA_BUS_FMT_YVYU8_1_5X8,
};

return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
case MEDIA_BUS_FMT_UYVY8_2X8:
{
u32 src_code[] = {
MEDIA_BUS_FMT_UYVY8_2X8,
MEDIA_BUS_FMT_UYVY8_1_5X8,
};

return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
case MEDIA_BUS_FMT_VYUY8_2X8:
{
u32 src_code[] = {
MEDIA_BUS_FMT_VYUY8_2X8,
MEDIA_BUS_FMT_VYUY8_1_5X8,
};

return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
default:
if (index > 0)
return 0;

return sink_code;
}
else if (vfe->camss->version == CAMSS_8x96)
switch (sink_code) {
case MEDIA_BUS_FMT_YUYV8_2X8:
{
u32 src_code[] = {
MEDIA_BUS_FMT_YUYV8_2X8,
MEDIA_BUS_FMT_YUYV8_1_5X8,
};

return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
case MEDIA_BUS_FMT_YVYU8_2X8:
{
u32 src_code[] = {
MEDIA_BUS_FMT_YVYU8_2X8,
MEDIA_BUS_FMT_YVYU8_1_5X8,
};

return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
case MEDIA_BUS_FMT_UYVY8_2X8:
{
u32 src_code[] = {
MEDIA_BUS_FMT_UYVY8_2X8,
MEDIA_BUS_FMT_UYVY8_1_5X8,
};

return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
case MEDIA_BUS_FMT_VYUY8_2X8:
{
u32 src_code[] = {
MEDIA_BUS_FMT_VYUY8_2X8,
MEDIA_BUS_FMT_VYUY8_1_5X8,
};

return vfe_find_code(src_code, ARRAY_SIZE(src_code),
index, src_req_code);
}
default:
if (index > 0)
return 0;

return sink_code;
}
else
return 0;
}

/*
* vfe_reset - Trigger reset on VFE module and wait to complete
* @vfe: VFE device
Expand Down Expand Up @@ -1388,11 +1513,11 @@ static void vfe_try_format(struct vfe_line *line,

case MSM_VFE_PAD_SRC:
/* Set and return a format same as sink pad */

code = fmt->code;

*fmt = *__vfe_get_format(line, cfg, MSM_VFE_PAD_SINK,
which);
*fmt = *__vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, which);

fmt->code = vfe_src_pad_code(line, fmt->code, 0, code);

if (line->id == VFE_LINE_PIX) {
struct v4l2_rect *rect;
Expand All @@ -1401,34 +1526,6 @@ static void vfe_try_format(struct vfe_line *line,

fmt->width = rect->width;
fmt->height = rect->height;

switch (fmt->code) {
case MEDIA_BUS_FMT_YUYV8_2X8:
if (code == MEDIA_BUS_FMT_YUYV8_1_5X8)
fmt->code = MEDIA_BUS_FMT_YUYV8_1_5X8;
else
fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
break;
case MEDIA_BUS_FMT_YVYU8_2X8:
if (code == MEDIA_BUS_FMT_YVYU8_1_5X8)
fmt->code = MEDIA_BUS_FMT_YVYU8_1_5X8;
else
fmt->code = MEDIA_BUS_FMT_YVYU8_2X8;
break;
case MEDIA_BUS_FMT_UYVY8_2X8:
default:
if (code == MEDIA_BUS_FMT_UYVY8_1_5X8)
fmt->code = MEDIA_BUS_FMT_UYVY8_1_5X8;
else
fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
break;
case MEDIA_BUS_FMT_VYUY8_2X8:
if (code == MEDIA_BUS_FMT_VYUY8_1_5X8)
fmt->code = MEDIA_BUS_FMT_VYUY8_1_5X8;
else
fmt->code = MEDIA_BUS_FMT_VYUY8_2X8;
break;
}
}

break;
Expand Down Expand Up @@ -1532,21 +1629,22 @@ static int vfe_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_mbus_code_enum *code)
{
struct vfe_line *line = v4l2_get_subdevdata(sd);
struct v4l2_mbus_framefmt *format;

if (code->pad == MSM_VFE_PAD_SINK) {
if (code->index >= line->nformats)
return -EINVAL;

code->code = line->formats[code->index].code;
} else {
if (code->index > 0)
return -EINVAL;
struct v4l2_mbus_framefmt *sink_fmt;

format = __vfe_get_format(line, cfg, MSM_VFE_PAD_SINK,
code->which);
sink_fmt = __vfe_get_format(line, cfg, MSM_VFE_PAD_SINK,
code->which);

code->code = format->code;
code->code = vfe_src_pad_code(line, sink_fmt->code,
code->index, 0);
if (!code->code)
return -EINVAL;
}

return 0;
Expand Down

0 comments on commit 07eeb34

Please sign in to comment.