linux/drivers/staging/media/imx/imx-ic-common.c
<<
>>
Prefs
   1/*
   2 * V4L2 Image Converter Subdev for Freescale i.MX5/6 SOC
   3 *
   4 * Copyright (c) 2014-2016 Mentor Graphics Inc.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 */
  11#include <linux/module.h>
  12#include <linux/platform_device.h>
  13#include <media/v4l2-device.h>
  14#include <media/v4l2-subdev.h>
  15#include "imx-media.h"
  16#include "imx-ic.h"
  17
  18#define IC_TASK_PRP IC_NUM_TASKS
  19#define IC_NUM_OPS  (IC_NUM_TASKS + 1)
  20
  21static struct imx_ic_ops *ic_ops[IC_NUM_OPS] = {
  22        [IC_TASK_PRP]            = &imx_ic_prp_ops,
  23        [IC_TASK_ENCODER]        = &imx_ic_prpencvf_ops,
  24        [IC_TASK_VIEWFINDER]     = &imx_ic_prpencvf_ops,
  25};
  26
  27static int imx_ic_probe(struct platform_device *pdev)
  28{
  29        struct imx_media_internal_sd_platformdata *pdata;
  30        struct imx_ic_priv *priv;
  31        int ret;
  32
  33        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  34        if (!priv)
  35                return -ENOMEM;
  36
  37        platform_set_drvdata(pdev, &priv->sd);
  38        priv->dev = &pdev->dev;
  39
  40        /* get our ipu_id, grp_id and IC task id */
  41        pdata = priv->dev->platform_data;
  42        priv->ipu_id = pdata->ipu_id;
  43        switch (pdata->grp_id) {
  44        case IMX_MEDIA_GRP_ID_IC_PRP:
  45                priv->task_id = IC_TASK_PRP;
  46                break;
  47        case IMX_MEDIA_GRP_ID_IC_PRPENC:
  48                priv->task_id = IC_TASK_ENCODER;
  49                break;
  50        case IMX_MEDIA_GRP_ID_IC_PRPVF:
  51                priv->task_id = IC_TASK_VIEWFINDER;
  52                break;
  53        default:
  54                return -EINVAL;
  55        }
  56
  57        v4l2_subdev_init(&priv->sd, ic_ops[priv->task_id]->subdev_ops);
  58        v4l2_set_subdevdata(&priv->sd, priv);
  59        priv->sd.internal_ops = ic_ops[priv->task_id]->internal_ops;
  60        priv->sd.entity.ops = ic_ops[priv->task_id]->entity_ops;
  61        priv->sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
  62        priv->sd.dev = &pdev->dev;
  63        priv->sd.owner = THIS_MODULE;
  64        priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
  65        priv->sd.grp_id = pdata->grp_id;
  66        strncpy(priv->sd.name, pdata->sd_name, sizeof(priv->sd.name));
  67
  68        ret = ic_ops[priv->task_id]->init(priv);
  69        if (ret)
  70                return ret;
  71
  72        ret = v4l2_async_register_subdev(&priv->sd);
  73        if (ret)
  74                ic_ops[priv->task_id]->remove(priv);
  75
  76        return ret;
  77}
  78
  79static int imx_ic_remove(struct platform_device *pdev)
  80{
  81        struct v4l2_subdev *sd = platform_get_drvdata(pdev);
  82        struct imx_ic_priv *priv = container_of(sd, struct imx_ic_priv, sd);
  83
  84        v4l2_info(sd, "Removing\n");
  85
  86        ic_ops[priv->task_id]->remove(priv);
  87
  88        v4l2_async_unregister_subdev(sd);
  89        media_entity_cleanup(&sd->entity);
  90
  91        return 0;
  92}
  93
  94static const struct platform_device_id imx_ic_ids[] = {
  95        { .name = "imx-ipuv3-ic" },
  96        { },
  97};
  98MODULE_DEVICE_TABLE(platform, imx_ic_ids);
  99
 100static struct platform_driver imx_ic_driver = {
 101        .probe = imx_ic_probe,
 102        .remove = imx_ic_remove,
 103        .id_table = imx_ic_ids,
 104        .driver = {
 105                .name = "imx-ipuv3-ic",
 106        },
 107};
 108module_platform_driver(imx_ic_driver);
 109
 110MODULE_DESCRIPTION("i.MX IC subdev driver");
 111MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
 112MODULE_LICENSE("GPL");
 113MODULE_ALIAS("platform:imx-ipuv3-ic");
 114