/* ************************************************************************* * Rockchip driver for CIF ISP 1.0 * (Based on Intel driver for sofiaxxx) * * Copyright (C) 2015 Intel Mobile Communications GmbH * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. ************************************************************************* */ #include #include #include "cif_isp10.h" #include "cif_isp10_img_src_ops.h" struct cif_isp10_img_src { void *img_src; const struct cif_isp10_img_src_ops *ops; }; struct cif_isp10_img_src *cif_isp10_img_src_to_img_src( CIF_ISP10_PLTFRM_DEVICE dev, struct pltfrm_soc_cfg *soc_cfg) { int ret = 0; int i; const char *device_type; struct cif_isp10_img_src *img_src; img_src = devm_kzalloc(dev, sizeof(*img_src), GFP_KERNEL); if (!img_src) { ret = -ENOMEM; goto err; } device_type = cif_isp10_pltfrm_get_device_type(dev); img_src->ops = NULL; for (i = 0; i < ARRAY_SIZE(cif_isp10_img_src_ops); i++) { if (!strcmp(device_type, cif_isp10_img_src_ops->device_type)) { img_src->ops = &cif_isp10_img_src_ops[i].ops; break; } } if (!img_src->ops) { cif_isp10_pltfrm_pr_err(NULL, "unsupported device type %s\n", device_type); ret = -EINVAL; goto err; } WARN_ON(!img_src->ops->to_img_src); WARN_ON(!img_src->ops->s_streaming); WARN_ON(!img_src->ops->s_power); WARN_ON(!img_src->ops->enum_strm_fmts); WARN_ON(!img_src->ops->s_strm_fmt); WARN_ON(!img_src->ops->g_ctrl); WARN_ON(!img_src->ops->s_ctrl); img_src->img_src = img_src->ops->to_img_src(dev, soc_cfg); if (IS_ERR_OR_NULL(img_src->img_src)) { cif_isp10_pltfrm_pr_err(NULL, "to_img_src failed!\n"); ret = -EFAULT; goto err; } return img_src; err: cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret); if (!IS_ERR_OR_NULL(img_src)) devm_kfree(dev, img_src); return ERR_PTR(ret); } int cif_isp10_img_src_s_streaming( struct cif_isp10_img_src *img_src, bool enable) { return img_src->ops->s_streaming(img_src->img_src, enable); } int cif_isp10_img_src_s_power( struct cif_isp10_img_src *img_src, bool on) { return img_src->ops->s_power(img_src->img_src, on); } int cif_isp10_img_src_enum_strm_fmts( struct cif_isp10_img_src *img_src, u32 index, struct cif_isp10_strm_fmt_desc *strm_fmt_desc) { return img_src->ops->enum_strm_fmts(img_src->img_src, index, strm_fmt_desc); } int cif_isp10_img_src_s_strm_fmt( struct cif_isp10_img_src *img_src, struct cif_isp10_strm_fmt *strm_fmt) { if (!img_src) { cif_isp10_pltfrm_pr_err(NULL, "img_src is NULL\n"); return -EINVAL; } return img_src->ops->s_strm_fmt(img_src->img_src, strm_fmt); } int cif_isp10_img_src_g_ctrl( struct cif_isp10_img_src *img_src, int id, int *val) { if (!img_src) { cif_isp10_pltfrm_pr_err(NULL, "img_src is NULL\n"); return -EINVAL; } return img_src->ops->g_ctrl(img_src->img_src, id, val); } int cif_isp10_img_src_s_ctrl( struct cif_isp10_img_src *img_src, int id, int val) { if (!img_src) { cif_isp10_pltfrm_pr_err(NULL, "img_src is NULL\n"); return -EINVAL; } return img_src->ops->s_ctrl(img_src->img_src, id, val); } int cif_isp10_img_src_s_ext_ctrls( struct cif_isp10_img_src *img_src, struct cif_isp10_img_src_ext_ctrl *ctrl) { if (!img_src) { cif_isp10_pltfrm_pr_err(NULL, "img_src is NULL\n"); return -EINVAL; } return img_src->ops->s_ext_ctrls(img_src->img_src, ctrl); } long cif_isp10_img_src_ioctl( struct cif_isp10_img_src *img_src, unsigned int cmd, void *arg) { if (!img_src) { cif_isp10_pltfrm_pr_err(NULL, "img_src is NULL\n"); return -EINVAL; } return img_src->ops->ioctl(img_src->img_src, cmd, arg); } const char *cif_isp10_img_src_g_name( struct cif_isp10_img_src *img_src) { if (!img_src) { cif_isp10_pltfrm_pr_err(NULL, "img_src is NULL\n"); return ERR_PTR(-EINVAL); } return img_src->ops->g_name(img_src->img_src); } void *cif_isp10_img_src_g_img_src( struct cif_isp10_img_src *img_src) { if (img_src) { return img_src->img_src; } return NULL; } int cif_isp10_img_src_s_frame_interval( struct cif_isp10_img_src *img_src, struct cif_isp10_frm_intrvl *frm_intrvl) { if (img_src) return img_src->ops->s_frame_interval( img_src->img_src, frm_intrvl); return -EINVAL; } int cif_isp10_img_src_g_frame_interval( struct cif_isp10_img_src *img_src, struct cif_isp10_frm_intrvl *frm_intrvl) { if (img_src) return img_src->ops->g_frame_interval( img_src->img_src, frm_intrvl); return -EINVAL; } int cif_isp10_img_src_enum_frame_size( struct cif_isp10_img_src *img_src, void *fse) { if (img_src) return img_src->ops->enum_frame_size( img_src->img_src, fse); return -EINVAL; }