isp10: rockchip: v0.1.6
[firefly-linux-kernel-4.4.55.git] / drivers / media / platform / rk-isp10 / cif_isp10_img_src.c
diff --git a/drivers/media/platform/rk-isp10/cif_isp10_img_src.c b/drivers/media/platform/rk-isp10/cif_isp10_img_src.c
new file mode 100644 (file)
index 0000000..7d8a18c
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ *************************************************************************
+ * 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 <linux/kernel.h>
+#include <linux/platform_data/rk_isp10_platform.h>
+#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);
+}
+