Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07eeb342 authored by Todor Tomov's avatar Todor Tomov Committed by Mauro Carvalho Chehab
Browse files

media: camss: vfe: Different format support on source pad



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: default avatarTodor Tomov <todor.tomov@linaro.org>
Signed-off-by: default avatarHans Verkuil <hansverk@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent cba3819d
Loading
Loading
Loading
Loading
+135 −37
Original line number Diff line number Diff line
@@ -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
@@ -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;
@@ -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;
@@ -1532,7 +1629,6 @@ 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)
@@ -1540,13 +1636,15 @@ static int vfe_enum_mbus_code(struct v4l2_subdev *sd,

		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,
		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;