static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) { u32 walign; if (!rvin_format_from_pixel(pix->pixelformat) || (vin->info->model == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32)) pix->pixelformat = RVIN_DEFAULT_FORMAT; switch (pix->field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: case V4L2_FIELD_NONE: case V4L2_FIELD_INTERLACED_TB: case V4L2_FIELD_INTERLACED_BT: case V4L2_FIELD_INTERLACED: break; case V4L2_FIELD_ALTERNATE: /* * Driver does not (yet) support outputting ALTERNATE to a * userspace. It does support outputting INTERLACED so use * the VIN hardware to combine the two fields. */ pix->field = V4L2_FIELD_INTERLACED; pix->height *= 2; break; default: pix->field = RVIN_DEFAULT_FIELD; break; } /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; /* Limit to VIN capabilities */ v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign, &pix->height, 4, vin->info->max_height, 2, 0); pix->bytesperline = rvin_format_bytesperline(pix); pix->sizeimage = rvin_format_sizeimage(pix); vin_dbg(vin, "Format %ux%u bpl: %u size: %u\n", pix->width, pix->height, pix->bytesperline, pix->sizeimage); }
static int __rvin_try_format(struct rvin_dev *vin, u32 which, struct v4l2_pix_format *pix, struct rvin_source_fmt *source) { const struct rvin_video_format *info; u32 rwidth, rheight, walign; /* Requested */ rwidth = pix->width; rheight = pix->height; /* Keep current field if no specific one is asked for */ if (pix->field == V4L2_FIELD_ANY) pix->field = vin->format.field; /* * Retrieve format information and select the current format if the * requested format isn't supported. */ info = rvin_format_from_pixel(pix->pixelformat); if (!info) { vin_dbg(vin, "Format %x not found, keeping %x\n", pix->pixelformat, vin->format.pixelformat); *pix = vin->format; pix->width = rwidth; pix->height = rheight; } /* Always recalculate */ pix->bytesperline = 0; pix->sizeimage = 0; /* Limit to source capabilities */ __rvin_try_format_source(vin, which, pix, source); switch (pix->field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: case V4L2_FIELD_ALTERNATE: pix->height /= 2; source->height /= 2; break; case V4L2_FIELD_NONE: case V4L2_FIELD_INTERLACED_TB: case V4L2_FIELD_INTERLACED_BT: case V4L2_FIELD_INTERLACED: break; default: pix->field = V4L2_FIELD_NONE; break; } /* If source can't match format try if VIN can scale */ if (source->width != rwidth || source->height != rheight) rvin_scale_try(vin, pix, rwidth, rheight); /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */ walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1; /* Limit to VIN capabilities */ v4l_bound_align_image(&pix->width, 2, RVIN_MAX_WIDTH, walign, &pix->height, 4, RVIN_MAX_HEIGHT, 2, 0); pix->bytesperline = max_t(u32, pix->bytesperline, rvin_format_bytesperline(pix)); pix->sizeimage = max_t(u32, pix->sizeimage, rvin_format_sizeimage(pix)); if (vin->chip == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32) { vin_err(vin, "pixel format XBGR32 not supported on M1\n"); return -EINVAL; } vin_dbg(vin, "Requested %ux%u Got %ux%u bpl: %d size: %d\n", rwidth, rheight, pix->width, pix->height, pix->bytesperline, pix->sizeimage); return 0; }