Beispiel #1
0
static void
csi2_try_format(struct iss_csi2_device *csi2, struct v4l2_subdev_fh *fh,
		unsigned int pad, struct v4l2_mbus_framefmt *fmt,
		enum v4l2_subdev_format_whence which)
{
	enum v4l2_mbus_pixelcode pixelcode;
	struct v4l2_mbus_framefmt *format;
	const struct iss_format_info *info;
	unsigned int i;

	switch (pad) {
	case CSI2_PAD_SINK:
		/* Clamp the width and height to valid range (1-8191). */
		for (i = 0; i < ARRAY_SIZE(csi2_input_fmts); i++) {
			if (fmt->code == csi2_input_fmts[i])
				break;
		}

		/* If not found, use SGRBG10 as default */
		if (i >= ARRAY_SIZE(csi2_input_fmts))
			fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;

		fmt->width = clamp_t(u32, fmt->width, 1, 8191);
		fmt->height = clamp_t(u32, fmt->height, 1, 8191);
		break;

	case CSI2_PAD_SOURCE:
		/* Source format same as sink format, except for DPCM
		 * compression.
		 */
		pixelcode = fmt->code;
		format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK, which);
		memcpy(fmt, format, sizeof(*fmt));

		/*
		 * Only Allow DPCM decompression, and check that the
		 * pattern is preserved
		 */
		info = omap4iss_video_format_info(fmt->code);
		if (info->uncompressed == pixelcode)
			fmt->code = pixelcode;
		break;
	}

	/* RGB, non-interlaced */
	fmt->colorspace = V4L2_COLORSPACE_SRGB;
	fmt->field = V4L2_FIELD_NONE;
}
Beispiel #2
0
int omap4iss_get_external_info(struct iss_pipeline *pipe,
			       struct media_link *link)
{
	struct iss_device *iss =
		container_of(pipe, struct iss_video, pipe)->iss;
	struct v4l2_subdev_format fmt;
	struct v4l2_ctrl *ctrl;
	int ret;

	if (!pipe->external)
		return 0;

	if (pipe->external_rate)
		return 0;

	memset(&fmt, 0, sizeof(fmt));

	fmt.pad = link->source->index;
	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(link->sink->entity),
			       pad, get_fmt, NULL, &fmt);
	if (ret < 0)
		return -EPIPE;

	pipe->external_bpp = omap4iss_video_format_info(fmt.format.code)->bpp;

	ctrl = v4l2_ctrl_find(pipe->external->ctrl_handler,
			      V4L2_CID_PIXEL_RATE);
	if (!ctrl) {
		dev_warn(iss->dev, "no pixel rate control in subdev %s\n",
			 pipe->external->name);
		return -EPIPE;
	}

	pipe->external_rate = v4l2_ctrl_g_ctrl_int64(ctrl);

	return 0;
}
Beispiel #3
0
/*
 * csi2_enum_mbus_code - Handle pixel format enumeration
 * @sd     : pointer to v4l2 subdev structure
 * @fh     : V4L2 subdev file handle
 * @code   : pointer to v4l2_subdev_mbus_code_enum structure
 * return -EINVAL or zero on success
 */
static int csi2_enum_mbus_code(struct v4l2_subdev *sd,
			       struct v4l2_subdev_fh *fh,
			       struct v4l2_subdev_mbus_code_enum *code)
{
	struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
	struct v4l2_mbus_framefmt *format;
	const struct iss_format_info *info;

	if (code->pad == CSI2_PAD_SINK) {
		if (code->index >= ARRAY_SIZE(csi2_input_fmts))
			return -EINVAL;

		code->code = csi2_input_fmts[code->index];
	} else {
		format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK,
					   V4L2_SUBDEV_FORMAT_TRY);
		switch (code->index) {
		case 0:
			/* Passthrough sink pad code */
			code->code = format->code;
			break;
		case 1:
			/* Uncompressed code */
			info = omap4iss_video_format_info(format->code);
			if (info->uncompressed == format->code)
				return -EINVAL;

			code->code = info->uncompressed;
			break;
		default:
			return -EINVAL;
		}
	}

	return 0;
}
Beispiel #4
0
static void ipipeif_configure(struct iss_ipipeif_device *ipipeif)
{
	struct iss_device *iss = to_iss_device(ipipeif);
	const struct iss_format_info *info;
	struct v4l2_mbus_framefmt *format;
	u32 isif_ccolp = 0;

	omap4iss_configure_bridge(iss, ipipeif->input);

	/* IPIPEIF_PAD_SINK */
	format = &ipipeif->formats[IPIPEIF_PAD_SINK];

	/* IPIPEIF with YUV422 input from ISIF */
	iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_IPIPEIF, IPIPEIF_CFG1,
		    IPIPEIF_CFG1_INPSRC1_MASK | IPIPEIF_CFG1_INPSRC2_MASK);

	/* Select ISIF/IPIPEIF input format */
	switch (format->code) {
	case V4L2_MBUS_FMT_UYVY8_1X16:
	case V4L2_MBUS_FMT_YUYV8_1X16:
		iss_reg_update(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_MODESET,
			       ISIF_MODESET_CCDMD | ISIF_MODESET_INPMOD_MASK |
			       ISIF_MODESET_CCDW_MASK,
			       ISIF_MODESET_INPMOD_YCBCR16);

		iss_reg_update(iss, OMAP4_ISS_MEM_ISP_IPIPEIF, IPIPEIF_CFG2,
			       IPIPEIF_CFG2_YUV8, IPIPEIF_CFG2_YUV16);

		break;
	case V4L2_MBUS_FMT_SGRBG10_1X10:
		isif_ccolp = ISIF_CCOLP_CP0_F0_GR |
			ISIF_CCOLP_CP1_F0_R |
			ISIF_CCOLP_CP2_F0_B |
			ISIF_CCOLP_CP3_F0_GB;
		goto cont_raw;
	case V4L2_MBUS_FMT_SRGGB10_1X10:
		isif_ccolp = ISIF_CCOLP_CP0_F0_R |
			ISIF_CCOLP_CP1_F0_GR |
			ISIF_CCOLP_CP2_F0_GB |
			ISIF_CCOLP_CP3_F0_B;
		goto cont_raw;
	case V4L2_MBUS_FMT_SBGGR10_1X10:
		isif_ccolp = ISIF_CCOLP_CP0_F0_B |
			ISIF_CCOLP_CP1_F0_GB |
			ISIF_CCOLP_CP2_F0_GR |
			ISIF_CCOLP_CP3_F0_R;
		goto cont_raw;
	case V4L2_MBUS_FMT_SGBRG10_1X10:
		isif_ccolp = ISIF_CCOLP_CP0_F0_GB |
			ISIF_CCOLP_CP1_F0_B |
			ISIF_CCOLP_CP2_F0_R |
			ISIF_CCOLP_CP3_F0_GR;
cont_raw:
		iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_IPIPEIF, IPIPEIF_CFG2,
			    IPIPEIF_CFG2_YUV16);

		iss_reg_update(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_MODESET,
			       ISIF_MODESET_CCDMD | ISIF_MODESET_INPMOD_MASK |
			       ISIF_MODESET_CCDW_MASK, ISIF_MODESET_INPMOD_RAW |
			       ISIF_MODESET_CCDW_2BIT);

		info = omap4iss_video_format_info(format->code);
		iss_reg_update(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_CGAMMAWD,
			       ISIF_CGAMMAWD_GWDI_MASK,
			       ISIF_CGAMMAWD_GWDI(info->bpp));

		/* Set RAW Bayer pattern */
		iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_CCOLP,
			      isif_ccolp);
		break;
	}

	iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_SPH, 0 & ISIF_SPH_MASK);
	iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_LNH,
		      (format->width - 1) & ISIF_LNH_MASK);
	iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_LNV,
		      (format->height - 1) & ISIF_LNV_MASK);

	/* Generate ISIF0 on the last line of the image */
	iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_VDINT(0),
		      format->height - 1);

	/* IPIPEIF_PAD_SOURCE_ISIF_SF */
	format = &ipipeif->formats[IPIPEIF_PAD_SOURCE_ISIF_SF];

	iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_HSIZE,
		      (ipipeif->video_out.bpl_value >> 5) &
		      ISIF_HSIZE_HSIZE_MASK);

	/* IPIPEIF_PAD_SOURCE_VP */
	/* Do nothing? */
}