/* * Decide whether desired output pixel code can be obtained with * the lane shifter by shifting the input pixel code. * @in: input pixelcode to shifter * @out: output pixelcode from shifter * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0] * * return true if the combination is possible * return false otherwise */ static bool isp_video_is_shiftable(enum v4l2_mbus_pixelcode in, enum v4l2_mbus_pixelcode out, unsigned int additional_shift) { const struct isp_format_info *in_info, *out_info; if (in == out) return true; in_info = omap3isp_video_format_info(in); out_info = omap3isp_video_format_info(out); if ((in_info->flavor == 0) || (out_info->flavor == 0)) return false; if (in_info->flavor != out_info->flavor) return false; return in_info->bpp - out_info->bpp + additional_shift <= 6; }
static void csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_pad_config *cfg, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { u32 pixelcode; struct v4l2_mbus_framefmt *format; const struct isp_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 = MEDIA_BUS_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, cfg, CSI2_PAD_SINK, which); memcpy(fmt, format, sizeof(*fmt)); /* * Only Allow DPCM decompression, and check that the * pattern is preserved */ info = omap3isp_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; }
/* * csi2_enum_mbus_code - Handle pixel format enumeration * @sd : pointer to v4l2 subdev structure * @cfg: V4L2 subdev pad configuration * @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_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code) { struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; const struct isp_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, cfg, 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 = omap3isp_video_format_info(format->code); if (info->uncompressed == format->code) return -EINVAL; code->code = info->uncompressed; break; default: return -EINVAL; } } return 0; }