static int bdisp_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int *nb_buf, unsigned int *nb_planes, unsigned int sizes[], void *allocators[]) { struct bdisp_ctx *ctx = vb2_get_drv_priv(vq); struct bdisp_frame *frame = ctx_get_frame(ctx, vq->type); if (IS_ERR(frame)) { dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); return PTR_ERR(frame); } if (!frame->fmt) { dev_err(ctx->bdisp_dev->dev, "Invalid format\n"); return -EINVAL; } if (fmt && fmt->fmt.pix.sizeimage < frame->sizeimage) return -EINVAL; *nb_planes = 1; sizes[0] = fmt ? fmt->fmt.pix.sizeimage : frame->sizeimage; allocators[0] = ctx->bdisp_dev->alloc_ctx; return 0; }
int rot_v4l2_g_fmt_mplane(struct file *file, void *priv, struct v4l2_format *f) { struct rot_ctx *ctx = priv; struct rot_fmt *rot_fmt; struct rot_frame *frame; struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; int i; frame = ctx_get_frame(ctx, f->type); if (IS_ERR(frame)) return PTR_ERR(frame); rot_fmt = frame->rot_fmt; pixm->width = frame->pix_mp.width; pixm->height = frame->pix_mp.height; pixm->pixelformat = frame->pix_mp.pixelformat; pixm->field = V4L2_FIELD_NONE; pixm->num_planes = frame->rot_fmt->num_planes; pixm->colorspace = 0; for (i = 0; i < pixm->num_planes; ++i) { pixm->plane_fmt[i].bytesperline = (pixm->width * rot_fmt->bitperpixel[i]) >> 3; pixm->plane_fmt[i].sizeimage = pixm->plane_fmt[i].bytesperline * pixm->height; rot_dbg("[%d] plane: bytesperline %d, sizeimage %d\n", i, pixm->plane_fmt[i].bytesperline, pixm->plane_fmt[i].sizeimage); } return 0; }
static int bdisp_queue_setup(struct vb2_queue *vq, unsigned int *nb_buf, unsigned int *nb_planes, unsigned int sizes[], struct device *alloc_devs[]) { struct bdisp_ctx *ctx = vb2_get_drv_priv(vq); struct bdisp_frame *frame = ctx_get_frame(ctx, vq->type); if (IS_ERR(frame)) { dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); return PTR_ERR(frame); } if (!frame->fmt) { dev_err(ctx->bdisp_dev->dev, "Invalid format\n"); return -EINVAL; } if (*nb_planes) return sizes[0] < frame->sizeimage ? -EINVAL : 0; *nb_planes = 1; sizes[0] = frame->sizeimage; return 0; }
static int gsc_m2m_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *reqbufs) { struct gsc_ctx *ctx = fh_to_ctx(fh); struct gsc_dev *gsc = ctx->gsc_dev; struct gsc_frame *frame; u32 max_cnt; max_cnt = (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? gsc->variant->in_buf_cnt : gsc->variant->out_buf_cnt; if (reqbufs->count > max_cnt) return -EINVAL; else if (reqbufs->count == 0) { if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) gsc_ctx_state_lock_clear(GSC_SRC_FMT, ctx); else gsc_ctx_state_lock_clear(GSC_DST_FMT, ctx); } gsc_set_protected_content(gsc, ctx->gsc_ctrls.drm_en->cur.val); frame = ctx_get_frame(ctx, reqbufs->type); frame->cacheable = ctx->gsc_ctrls.cacheable->val; gsc->vb2->set_cacheable(gsc->alloc_ctx, frame->cacheable); return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); }
static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], void *allocators[]) { struct fimc_ctx *ctx = vb2_get_drv_priv(vq); struct fimc_frame *f; int i; f = ctx_get_frame(ctx, vq->type); if (IS_ERR(f)) return PTR_ERR(f); /* * Return number of non-contigous planes (plane buffers) * depending on the configured color format. */ if (!f->fmt) return -EINVAL; *num_planes = f->fmt->memplanes; for (i = 0; i < f->fmt->memplanes; i++) { sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8; allocators[i] = ctx->fimc_dev->alloc_ctx; } return 0; }
int gsc_g_fmt_mplane(struct gsc_ctx *ctx, struct v4l2_format *f) { struct gsc_frame *frame; struct v4l2_pix_format_mplane *pix_mp; int i; frame = ctx_get_frame(ctx, f->type); if (IS_ERR(frame)) return PTR_ERR(frame); pix_mp = &f->fmt.pix_mp; pix_mp->width = frame->f_width; pix_mp->height = frame->f_height; pix_mp->field = V4L2_FIELD_NONE; pix_mp->pixelformat = frame->fmt->pixelformat; pix_mp->num_planes = frame->fmt->num_planes; pix_mp->colorspace = ctx->out_colorspace; for (i = 0; i < pix_mp->num_planes; ++i) { pix_mp->plane_fmt[i].bytesperline = (frame->f_width * frame->fmt->depth[i]) / 8; pix_mp->plane_fmt[i].sizeimage = pix_mp->plane_fmt[i].bytesperline * frame->f_height; } return 0; }
static int jpeg_enc_vidioc_s_fmt_out(struct file *file, void *priv, struct v4l2_format *f) { struct jpeg_ctx *ctx = priv; struct vb2_queue *vq; struct v4l2_pix_format_mplane *pix; struct jpeg_fmt *fmt; struct jpeg_frame *frame; int ret; int i; ret = jpeg_enc_vidioc_try_fmt(file, priv, f); if (ret) return ret; vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); if (!vq) return -EINVAL; if (vb2_is_busy(vq)) { v4l2_err(&ctx->jpeg_dev->v4l2_dev, "queue (%d) busy\n", f->type); return -EBUSY; } /* TODO: width & height has to be multiple of two */ pix = &f->fmt.pix_mp; fmt = find_format(f); frame = ctx_get_frame(ctx, f->type); if (IS_ERR(frame)) return PTR_ERR(frame); frame->jpeg_fmt = fmt; if (!frame->jpeg_fmt) { v4l2_err(&ctx->jpeg_dev->v4l2_dev, "not supported format values\n"); return -EINVAL; } for (i = 0; i < fmt->memplanes; i++) { ctx->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; ctx->param.enc_param.in_depth[i] = fmt->depth[i]; } frame->width = pix->width; frame->height = pix->height; frame->pixelformat = pix->pixelformat; ctx->param.enc_param.in_width = pix->width; ctx->param.enc_param.in_height = pix->height; ctx->param.enc_param.in_plane = fmt->memplanes; ctx->param.enc_param.in_fmt = fmt->color; return 0; }
static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh, struct v4l2_format *f) { struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_frame *frame = ctx_get_frame(ctx, f->type); if (IS_ERR(frame)) return PTR_ERR(frame); return fimc_fill_format(frame, f); }
int gsc_g_crop(struct gsc_ctx *ctx, struct v4l2_crop *cr) { struct gsc_frame *frame; frame = ctx_get_frame(ctx, cr->type); if (IS_ERR(frame)) return PTR_ERR(frame); memcpy(&cr->c, &frame->crop, sizeof(struct v4l2_rect)); return 0; }
int gsc_g_crop(struct gsc_ctx *ctx, struct v4l2_crop *cr) { struct gsc_frame *frame; frame = ctx_get_frame(ctx, cr->type); if (IS_ERR(frame)) return PTR_ERR(frame); cr->c = frame->crop; return 0; }
static int rot_v4l2_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) { struct rot_ctx *ctx = fh; struct rot_frame *frame; frame = ctx_get_frame(ctx, cr->type); if (IS_ERR(frame)) return PTR_ERR(frame); cr->c = frame->crop; return 0; }
static int rot_v4l2_s_fmt_mplane(struct file *file, void *priv, struct v4l2_format *f) { struct rot_ctx *ctx = priv; struct vb2_queue *vq; struct rot_frame *frame; struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; int i, ret = 0; vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); if (vb2_is_streaming(vq)) { rot_err("device is busy\n"); return -EBUSY; } ret = rot_v4l2_try_fmt_mplane(file, priv, f); if (ret < 0) return ret; frame = ctx_get_frame(ctx, f->type); if (IS_ERR(frame)) return PTR_ERR(frame); set_bit(CTX_PARAMS, &ctx->flags); frame->rot_fmt = rot_find_format(f); if (!frame->rot_fmt) { rot_err("not supported format values\n"); return -EINVAL; } rot_adjust_pixminfo(ctx, frame, pixm); frame->pix_mp.pixelformat = pixm->pixelformat; frame->pix_mp.width = pixm->width; frame->pix_mp.height = pixm->height; /* * Shouldn't call s_crop or g_crop before called g_fmt or s_fmt. * Let's assume that we can keep the order. */ frame->crop.width = pixm->width; frame->crop.height = pixm->height; for (i = 0; i < frame->rot_fmt->num_planes; ++i) frame->bytesused[i] = (pixm->width * pixm->height * frame->rot_fmt->bitperpixel[i]) >> 3; return 0; }
static int bdisp_buf_prepare(struct vb2_buffer *vb) { struct bdisp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct bdisp_frame *frame = ctx_get_frame(ctx, vb->vb2_queue->type); if (IS_ERR(frame)) { dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); return PTR_ERR(frame); } if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) vb2_set_plane_payload(vb, 0, frame->sizeimage); return 0; }
static int fimc_buf_prepare(struct vb2_buffer *vb) { struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct fimc_frame *frame; int i; frame = ctx_get_frame(ctx, vb->vb2_queue->type); if (IS_ERR(frame)) return PTR_ERR(frame); for (i = 0; i < frame->fmt->memplanes; i++) vb2_set_plane_payload(vb, i, frame->payload[i]); return 0; }
static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) { struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_frame *frame; frame = ctx_get_frame(ctx, cr->type); if (IS_ERR(frame)) return PTR_ERR(frame); cr->c.left = frame->offs_h; cr->c.top = frame->offs_v; cr->c.width = frame->width; cr->c.height = frame->height; return 0; }
static int rot_v4l2_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) { struct rot_ctx *ctx = fh; struct rot_frame *frame; struct v4l2_pix_format_mplane *pixm; int i; frame = ctx_get_frame(ctx, cr->type); if (IS_ERR(frame)) return PTR_ERR(frame); if (!test_bit(CTX_PARAMS, &ctx->flags)) { rot_err("color format is not set\n"); return -EINVAL; } if (cr->c.left < 0 || cr->c.top < 0 || cr->c.width < 0 || cr->c.height < 0) { rot_err("crop value is negative\n"); return -EINVAL; } pixm = &frame->pix_mp; rot_adjust_cropinfo(ctx, frame, &cr->c); rot_bound_align_image(ctx, frame->rot_fmt, &cr->c.width, &cr->c.height); /* Adjust left/top if cropping rectangle is out of bounds */ if (cr->c.left + cr->c.width > pixm->width) { rot_warn("out of bound left cropping size:left %d, width %d\n", cr->c.left, cr->c.width); cr->c.left = pixm->width - cr->c.width; } if (cr->c.top + cr->c.height > pixm->height) { rot_warn("out of bound top cropping size:top %d, height %d\n", cr->c.top, cr->c.height); cr->c.top = pixm->height - cr->c.height; } frame->crop = cr->c; for (i = 0; i < frame->rot_fmt->num_planes; ++i) frame->bytesused[i] = (cr->c.width * cr->c.height * frame->rot_fmt->bitperpixel[i]) >> 3; return 0; }
static int gsc_m2m_buf_prepare(struct vb2_buffer *vb) { struct gsc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct gsc_frame *frame; int i; frame = ctx_get_frame(ctx, vb->vb2_queue->type); if (IS_ERR(frame)) return PTR_ERR(frame); if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { for (i = 0; i < frame->fmt->num_planes; i++) vb2_set_plane_payload(vb, i, frame->payload[i]); } return 0; }
static int gsc_capture_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *reqbufs) { struct gsc_dev *gsc = video_drvdata(file); struct gsc_capture_device *cap = &gsc->cap; struct gsc_frame *frame; int ret; frame = ctx_get_frame(cap->ctx, reqbufs->type); ret = vb2_reqbufs(&cap->vbq, reqbufs); if (!ret) cap->reqbufs_cnt = reqbufs->count; return ret; }
static int fimc_m2m_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cr) { struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_frame *frame; frame = ctx_get_frame(ctx, cr->type); if (IS_ERR(frame)) return PTR_ERR(frame); cr->bounds.left = 0; cr->bounds.top = 0; cr->bounds.width = frame->o_width; cr->bounds.height = frame->o_height; cr->defrect = cr->bounds; return 0; }
static int rot_v4l2_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cr) { struct rot_ctx *ctx = fh; struct rot_frame *frame; frame = ctx_get_frame(ctx, cr->type); if (IS_ERR(frame)) return PTR_ERR(frame); cr->bounds.left = 0; cr->bounds.top = 0; cr->bounds.width = frame->pix_mp.width; cr->bounds.height = frame->pix_mp.height; cr->defrect = cr->bounds; return 0; }
static int rot_vb2_buf_prepare(struct vb2_buffer *vb) { struct rot_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct rot_frame *frame; int i; frame = ctx_get_frame(ctx, vb->vb2_queue->type); if (IS_ERR(frame)) return PTR_ERR(frame); if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { for (i = 0; i < frame->rot_fmt->num_planes; i++) vb2_set_plane_payload(vb, i, frame->bytesused[i]); } if (frame->cacheable) ctx->rot_dev->vb2->cache_flush(vb, frame->rot_fmt->num_planes); return 0; }
static int gsc_m2m_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], struct device *alloc_devs[]) { struct gsc_ctx *ctx = vb2_get_drv_priv(vq); struct gsc_frame *frame; int i; frame = ctx_get_frame(ctx, vq->type); if (IS_ERR(frame)) return PTR_ERR(frame); if (!frame->fmt) return -EINVAL; *num_planes = frame->fmt->num_planes; for (i = 0; i < frame->fmt->num_planes; i++) sizes[i] = frame->payload[i]; return 0; }
static int rot_v4l2_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *reqbufs) { struct rot_ctx *ctx = priv; struct rot_dev *rot = ctx->rot_dev; struct rot_frame *frame; frame = ctx_get_frame(ctx, reqbufs->type); if (IS_ERR(frame)) return PTR_ERR(frame); if (frame == &ctx->s_frame) clear_bit(CTX_SRC, &ctx->flags); else if (frame == &ctx->d_frame) clear_bit(CTX_DST, &ctx->flags); frame->cacheable = ctx->cacheable; rot->vb2->set_cacheable(rot->alloc_ctx, frame->cacheable); return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); }
static int jpeg_enc_vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) { struct jpeg_ctx *ctx = priv; struct v4l2_pix_format_mplane *pixm; struct jpeg_enc_param *enc_param = &ctx->param.enc_param; struct jpeg_frame *frame; frame = ctx_get_frame(ctx, f->type); if (IS_ERR(frame)) return PTR_ERR(frame); pixm = &f->fmt.pix_mp; pixm->field = V4L2_FIELD_NONE; if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { pixm->pixelformat = frame->pixelformat; pixm->num_planes = enc_param->in_plane; pixm->width = enc_param->in_width; pixm->height = enc_param->in_height; } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { pixm->pixelformat = frame->pixelformat; pixm->num_planes = enc_param->out_plane; pixm->width = enc_param->out_width; pixm->height = enc_param->out_height; } else { v4l2_err(&ctx->jpeg_dev->v4l2_dev, "Wrong buffer/video queue type (%d)\n", f->type); } return 0; }
static int rot_vb2_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, unsigned int *num_planes, unsigned long sizes[], void *alloc_ctxs[]) { struct rot_ctx *ctx = vb2_get_drv_priv(vq); struct rot_frame *frame; int i; frame = ctx_get_frame(ctx, vq->type); if (IS_ERR(frame)) return PTR_ERR(frame); /* Get number of planes from format_list in driver */ *num_planes = frame->rot_fmt->num_planes; for (i = 0; i < frame->rot_fmt->num_planes; i++) { sizes[i] = (frame->pix_mp.width * frame->pix_mp.height * frame->rot_fmt->bitperpixel[i]) >> 3; alloc_ctxs[i] = ctx->rot_dev->alloc_ctx; } return 0; }
static int gsc_m2m_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], void *allocators[]) { struct gsc_ctx *ctx = vb2_get_drv_priv(vq); struct gsc_frame *frame; int i; frame = ctx_get_frame(ctx, vq->type); if (IS_ERR(frame)) return PTR_ERR(frame); if (!frame->fmt) return -EINVAL; *num_planes = frame->fmt->num_planes; for (i = 0; i < frame->fmt->num_planes; i++) { sizes[i] = get_plane_size(frame, i); allocators[i] = ctx->gsc_dev->alloc_ctx; } return 0; }
static int bdisp_g_selection(struct file *file, void *fh, struct v4l2_selection *s) { struct bdisp_frame *frame; struct bdisp_ctx *ctx = fh_to_ctx(fh); if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { /* Composing / capture is not supported */ dev_dbg(ctx->bdisp_dev->dev, "Not supported for capture\n"); return -EINVAL; } frame = ctx_get_frame(ctx, s->type); if (IS_ERR(frame)) { dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); return PTR_ERR(frame); } switch (s->target) { case V4L2_SEL_TGT_CROP: /* cropped frame */ s->r = frame->crop; break; case V4L2_SEL_TGT_CROP_DEFAULT: case V4L2_SEL_TGT_CROP_BOUNDS: /* complete frame */ s->r.left = 0; s->r.top = 0; s->r.width = frame->width; s->r.height = frame->height; break; default: dev_dbg(ctx->bdisp_dev->dev, "Invalid target\n"); return -EINVAL; } return 0; }
static int bdisp_g_fmt(struct file *file, void *fh, struct v4l2_format *f) { struct bdisp_ctx *ctx = fh_to_ctx(fh); struct v4l2_pix_format *pix = &f->fmt.pix; struct bdisp_frame *frame = ctx_get_frame(ctx, f->type); if (IS_ERR(frame)) { dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); return PTR_ERR(frame); } pix = &f->fmt.pix; pix->width = frame->width; pix->height = frame->height; pix->pixelformat = frame->fmt->pixelformat; pix->field = frame->field; pix->bytesperline = frame->bytesperline; pix->sizeimage = frame->sizeimage; pix->colorspace = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? frame->colorspace : bdisp_dflt_fmt.colorspace; return 0; }
static int gsc_m2m_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *reqbufs) { struct gsc_ctx *ctx = fh_to_ctx(fh); struct gsc_dev *gsc = ctx->gsc_dev; struct gsc_frame *frame; u32 max_cnt; max_cnt = (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? gsc->variant->in_buf_cnt : gsc->variant->out_buf_cnt; if (reqbufs->count > max_cnt) { return -EINVAL; } else if (reqbufs->count == 0) { if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) gsc_ctx_state_lock_clear(GSC_SRC_FMT, ctx); else gsc_ctx_state_lock_clear(GSC_DST_FMT, ctx); } frame = ctx_get_frame(ctx, reqbufs->type); return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); }
static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], struct device *alloc_devs[]) { struct fimc_ctx *ctx = vb2_get_drv_priv(vq); struct fimc_frame *f; int i; f = ctx_get_frame(ctx, vq->type); if (IS_ERR(f)) return PTR_ERR(f); /* * Return number of non-contiguous planes (plane buffers) * depending on the configured color format. */ if (!f->fmt) return -EINVAL; *num_planes = f->fmt->memplanes; for (i = 0; i < f->fmt->memplanes; i++) sizes[i] = f->payload[i]; return 0; }