linux/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2012 Texas Instruments Inc
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation version 2.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * Contributors:
  15 *      Manjunath Hadli <manjunath.hadli@ti.com>
  16 *      Prabhakar Lad <prabhakar.lad@ti.com>
  17 *
  18 *
  19 * Driver name : VPFE Capture driver
  20 *    VPFE Capture driver allows applications to capture and stream video
  21 *    frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
  22 *    TVP5146 or  Raw Bayer RGB image data from an image sensor
  23 *    such as Microns' MT9T001, MT9T031 etc.
  24 *
  25 *    These SoCs have, in common, a Video Processing Subsystem (VPSS) that
  26 *    consists of a Video Processing Front End (VPFE) for capturing
  27 *    video/raw image data and Video Processing Back End (VPBE) for displaying
  28 *    YUV data through an in-built analog encoder or Digital LCD port. This
  29 *    driver is for capture through VPFE. A typical EVM using these SoCs have
  30 *    following high level configuration.
  31 *
  32 *    decoder(TVP5146/          YUV/
  33 *      MT9T001)   -->  Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
  34 *                      data input              |      |
  35 *                                                      V      |
  36 *                                                    SDRAM    |
  37 *                                                             V
  38 *                                                         Image Processor
  39 *                                                             |
  40 *                                                             V
  41 *                                                           SDRAM
  42 *    The data flow happens from a decoder connected to the VPFE over a
  43 *    YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
  44 *    and to the input of VPFE through an optional MUX (if more inputs are
  45 *    to be interfaced on the EVM). The input data is first passed through
  46 *    CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
  47 *    does very little or no processing on YUV data and does pre-process Raw
  48 *    Bayer RGB data through modules such as Defect Pixel Correction (DFC)
  49 *    Color Space Conversion (CSC), data gain/offset etc. After this, data
  50 *    can be written to SDRAM or can be connected to the image processing
  51 *    block such as IPIPE (on DM355/DM365 only).
  52 *
  53 *    Features supported
  54 *              - MMAP IO
  55 *              - USERPTR IO
  56 *              - Capture using TVP5146 over BT.656
  57 *              - Support for interfacing decoders using sub device model
  58 *              - Work with DM365 or DM355 or DM6446 CCDC to do Raw Bayer
  59 *                RGB/YUV data capture to SDRAM.
  60 *              - Chaining of Image Processor
  61 *              - SINGLE-SHOT mode
  62 */
  63
  64#include <linux/interrupt.h>
  65#include <linux/module.h>
  66#include <linux/slab.h>
  67
  68#include "vpfe.h"
  69#include "vpfe_mc_capture.h"
  70
  71static bool debug;
  72static bool interface;
  73
  74module_param(interface, bool, 0444);
  75module_param(debug, bool, 0644);
  76
  77/*
  78 * VPFE capture can be used for capturing video such as from TVP5146 or TVP7002
  79 * and for capture raw bayer data from camera sensors such as mt9p031. At this
  80 * point there is problem in co-existence of mt9p031 and tvp5146 due to i2c
  81 * address collision. So set the variable below from bootargs to do either video
  82 * capture or camera capture.
  83 * interface = 0 - video capture (from TVP514x or such),
  84 * interface = 1 - Camera capture (from mt9p031 or such)
  85 * Re-visit this when we fix the co-existence issue
  86 */
  87MODULE_PARM_DESC(interface, "interface 0-1 (default:0)");
  88MODULE_PARM_DESC(debug, "Debug level 0-1");
  89
  90MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
  91MODULE_LICENSE("GPL");
  92MODULE_AUTHOR("Texas Instruments");
  93
  94/* map mbus_fmt to pixelformat */
  95void mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
  96                           struct v4l2_pix_format *pix)
  97{
  98        switch (mbus->code) {
  99        case MEDIA_BUS_FMT_UYVY8_2X8:
 100                pix->pixelformat = V4L2_PIX_FMT_UYVY;
 101                pix->bytesperline = pix->width * 2;
 102                break;
 103
 104        case MEDIA_BUS_FMT_YUYV8_2X8:
 105                pix->pixelformat = V4L2_PIX_FMT_YUYV;
 106                pix->bytesperline = pix->width * 2;
 107                break;
 108
 109        case MEDIA_BUS_FMT_YUYV10_1X20:
 110                pix->pixelformat = V4L2_PIX_FMT_UYVY;
 111                pix->bytesperline = pix->width * 2;
 112                break;
 113
 114        case MEDIA_BUS_FMT_SGRBG12_1X12:
 115                pix->pixelformat = V4L2_PIX_FMT_SBGGR16;
 116                pix->bytesperline = pix->width * 2;
 117                break;
 118
 119        case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
 120                pix->pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8;
 121                pix->bytesperline = pix->width;
 122                break;
 123
 124        case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
 125                pix->pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8;
 126                pix->bytesperline = pix->width;
 127                break;
 128
 129        case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
 130                pix->pixelformat = V4L2_PIX_FMT_NV12;
 131                pix->bytesperline = pix->width;
 132                break;
 133
 134        case MEDIA_BUS_FMT_Y8_1X8:
 135                pix->pixelformat = V4L2_PIX_FMT_GREY;
 136                pix->bytesperline = pix->width;
 137                break;
 138
 139        case MEDIA_BUS_FMT_UV8_1X8:
 140                pix->pixelformat = V4L2_PIX_FMT_UV8;
 141                pix->bytesperline = pix->width;
 142                break;
 143
 144        default:
 145                pr_err("Invalid mbus code set\n");
 146        }
 147        /* pitch should be 32 bytes aligned */
 148        pix->bytesperline = ALIGN(pix->bytesperline, 32);
 149        if (pix->pixelformat == V4L2_PIX_FMT_NV12)
 150                pix->sizeimage = pix->bytesperline * pix->height +
 151                                ((pix->bytesperline * pix->height) >> 1);
 152        else
 153                pix->sizeimage = pix->bytesperline * pix->height;
 154}
 155
 156/* ISR for VINT0*/
 157static irqreturn_t vpfe_isr(int irq, void *dev_id)
 158{
 159        struct vpfe_device *vpfe_dev = dev_id;
 160
 161        v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "%s\n", __func__);
 162        vpfe_isif_buffer_isr(&vpfe_dev->vpfe_isif);
 163        vpfe_resizer_buffer_isr(&vpfe_dev->vpfe_resizer);
 164        return IRQ_HANDLED;
 165}
 166
 167/* vpfe_vdint1_isr() - isr handler for VINT1 interrupt */
 168static irqreturn_t vpfe_vdint1_isr(int irq, void *dev_id)
 169{
 170        struct vpfe_device *vpfe_dev = dev_id;
 171
 172        v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "%s\n", __func__);
 173        vpfe_isif_vidint1_isr(&vpfe_dev->vpfe_isif);
 174        return IRQ_HANDLED;
 175}
 176
 177/* vpfe_imp_dma_isr() - ISR for ipipe dma completion */
 178static irqreturn_t vpfe_imp_dma_isr(int irq, void *dev_id)
 179{
 180        struct vpfe_device *vpfe_dev = dev_id;
 181
 182        v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "%s\n", __func__);
 183        vpfe_ipipeif_ss_buffer_isr(&vpfe_dev->vpfe_ipipeif);
 184        vpfe_resizer_dma_isr(&vpfe_dev->vpfe_resizer);
 185        return IRQ_HANDLED;
 186}
 187
 188/*
 189 * vpfe_disable_clock() - Disable clocks for vpfe capture driver
 190 * @vpfe_dev - ptr to vpfe capture device
 191 *
 192 * Disables clocks defined in vpfe configuration. The function
 193 * assumes that at least one clock is to be defined which is
 194 * true as of now.
 195 */
 196static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
 197{
 198        struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
 199        int i;
 200
 201        for (i = 0; i < vpfe_cfg->num_clocks; i++) {
 202                clk_disable_unprepare(vpfe_dev->clks[i]);
 203                clk_put(vpfe_dev->clks[i]);
 204        }
 205        kzfree(vpfe_dev->clks);
 206        v4l2_info(vpfe_dev->pdev->driver, "vpfe capture clocks disabled\n");
 207}
 208
 209/*
 210 * vpfe_enable_clock() - Enable clocks for vpfe capture driver
 211 * @vpfe_dev - ptr to vpfe capture device
 212 *
 213 * Enables clocks defined in vpfe configuration. The function
 214 * assumes that at least one clock is to be defined which is
 215 * true as of now.
 216 */
 217static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
 218{
 219        struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
 220        int ret = -EFAULT;
 221        int i;
 222
 223        if (!vpfe_cfg->num_clocks)
 224                return 0;
 225
 226        vpfe_dev->clks = kcalloc(vpfe_cfg->num_clocks,
 227                                 sizeof(*vpfe_dev->clks), GFP_KERNEL);
 228        if (!vpfe_dev->clks)
 229                return -ENOMEM;
 230
 231        for (i = 0; i < vpfe_cfg->num_clocks; i++) {
 232                if (vpfe_cfg->clocks[i] == NULL) {
 233                        v4l2_err(vpfe_dev->pdev->driver,
 234                                "clock %s is not defined in vpfe config\n",
 235                                vpfe_cfg->clocks[i]);
 236                        goto out;
 237                }
 238
 239                vpfe_dev->clks[i] =
 240                                clk_get(vpfe_dev->pdev, vpfe_cfg->clocks[i]);
 241                if (IS_ERR(vpfe_dev->clks[i])) {
 242                        v4l2_err(vpfe_dev->pdev->driver,
 243                                "Failed to get clock %s\n",
 244                                vpfe_cfg->clocks[i]);
 245                        goto out;
 246                }
 247
 248                if (clk_prepare_enable(vpfe_dev->clks[i])) {
 249                        v4l2_err(vpfe_dev->pdev->driver,
 250                                "vpfe clock %s not enabled\n",
 251                                vpfe_cfg->clocks[i]);
 252                        goto out;
 253                }
 254
 255                v4l2_info(vpfe_dev->pdev->driver, "vpss clock %s enabled",
 256                          vpfe_cfg->clocks[i]);
 257        }
 258
 259        return 0;
 260out:
 261        for (i = 0; i < vpfe_cfg->num_clocks; i++)
 262                if (!IS_ERR(vpfe_dev->clks[i])) {
 263                        clk_disable_unprepare(vpfe_dev->clks[i]);
 264                        clk_put(vpfe_dev->clks[i]);
 265                }
 266
 267        v4l2_err(vpfe_dev->pdev->driver, "Failed to enable clocks\n");
 268        kzfree(vpfe_dev->clks);
 269
 270        return ret;
 271}
 272
 273/*
 274 * vpfe_detach_irq() - Detach IRQs for vpfe capture driver
 275 * @vpfe_dev - ptr to vpfe capture device
 276 *
 277 * Detach all IRQs defined in vpfe configuration.
 278 */
 279static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
 280{
 281        free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
 282        free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
 283        free_irq(vpfe_dev->imp_dma_irq, vpfe_dev);
 284}
 285
 286/*
 287 * vpfe_attach_irq() - Attach IRQs for vpfe capture driver
 288 * @vpfe_dev - ptr to vpfe capture device
 289 *
 290 * Attach all IRQs defined in vpfe configuration.
 291 */
 292static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
 293{
 294        int ret;
 295
 296        ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0,
 297                          "vpfe_capture0", vpfe_dev);
 298        if (ret < 0) {
 299                v4l2_err(&vpfe_dev->v4l2_dev,
 300                        "Error: requesting VINT0 interrupt\n");
 301                return ret;
 302        }
 303
 304        ret = request_irq(vpfe_dev->ccdc_irq1, vpfe_vdint1_isr, 0,
 305                          "vpfe_capture1", vpfe_dev);
 306        if (ret < 0) {
 307                v4l2_err(&vpfe_dev->v4l2_dev,
 308                        "Error: requesting VINT1 interrupt\n");
 309                free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
 310                return ret;
 311        }
 312
 313        ret = request_irq(vpfe_dev->imp_dma_irq, vpfe_imp_dma_isr,
 314                          0, "Imp_Sdram_Irq", vpfe_dev);
 315        if (ret < 0) {
 316                v4l2_err(&vpfe_dev->v4l2_dev,
 317                         "Error: requesting IMP IRQ interrupt\n");
 318                free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
 319                free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
 320                return ret;
 321        }
 322
 323        return 0;
 324}
 325
 326/*
 327 * register_i2c_devices() - register all i2c v4l2 subdevs
 328 * @vpfe_dev - ptr to vpfe capture device
 329 *
 330 * register all i2c v4l2 subdevs
 331 */
 332static int register_i2c_devices(struct vpfe_device *vpfe_dev)
 333{
 334        struct vpfe_ext_subdev_info *sdinfo;
 335        struct vpfe_config *vpfe_cfg;
 336        struct i2c_adapter *i2c_adap;
 337        unsigned int num_subdevs;
 338        int ret;
 339        int i;
 340        int k;
 341
 342        vpfe_cfg = vpfe_dev->cfg;
 343        i2c_adap = i2c_get_adapter(1);
 344        num_subdevs = vpfe_cfg->num_subdevs;
 345        vpfe_dev->sd =
 346                  kcalloc(num_subdevs, sizeof(struct v4l2_subdev *),
 347                          GFP_KERNEL);
 348        if (!vpfe_dev->sd)
 349                return -ENOMEM;
 350
 351        for (i = 0, k = 0; i < num_subdevs; i++) {
 352                sdinfo = &vpfe_cfg->sub_devs[i];
 353                /*
 354                 * register subdevices based on interface setting. Currently
 355                 * tvp5146 and mt9p031 cannot co-exists due to i2c address
 356                 * conflicts. So only one of them is registered. Re-visit this
 357                 * once we have support for i2c switch handling in i2c driver
 358                 * framework
 359                 */
 360                if (interface == sdinfo->is_camera) {
 361                        /* setup input path */
 362                        if (vpfe_cfg->setup_input &&
 363                                vpfe_cfg->setup_input(sdinfo->grp_id) < 0) {
 364                                ret = -EFAULT;
 365                                v4l2_info(&vpfe_dev->v4l2_dev,
 366                                          "could not setup input for %s\n",
 367                                                sdinfo->module_name);
 368                                goto probe_sd_out;
 369                        }
 370                        /* Load up the subdevice */
 371                        vpfe_dev->sd[k] =
 372                                v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
 373                                                  i2c_adap, &sdinfo->board_info,
 374                                                  NULL);
 375                        if (vpfe_dev->sd[k]) {
 376                                v4l2_info(&vpfe_dev->v4l2_dev,
 377                                                "v4l2 sub device %s registered\n",
 378                                                sdinfo->module_name);
 379
 380                                vpfe_dev->sd[k]->grp_id = sdinfo->grp_id;
 381                                k++;
 382
 383                                sdinfo->registered = 1;
 384                        }
 385                } else {
 386                        v4l2_info(&vpfe_dev->v4l2_dev,
 387                                  "v4l2 sub device %s is not registered\n",
 388                                  sdinfo->module_name);
 389                }
 390        }
 391        vpfe_dev->num_ext_subdevs = k;
 392
 393        return 0;
 394
 395probe_sd_out:
 396        kzfree(vpfe_dev->sd);
 397
 398        return ret;
 399}
 400
 401/*
 402 * vpfe_register_entities() - register all v4l2 subdevs and media entities
 403 * @vpfe_dev - ptr to vpfe capture device
 404 *
 405 * register all v4l2 subdevs, media entities, and creates links
 406 * between entities
 407 */
 408static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
 409{
 410        unsigned int flags = 0;
 411        int ret;
 412        int i;
 413
 414        /* register i2c devices first */
 415        ret = register_i2c_devices(vpfe_dev);
 416        if (ret)
 417                return ret;
 418
 419        /* register rest of the sub-devs */
 420        ret = vpfe_isif_register_entities(&vpfe_dev->vpfe_isif,
 421                                          &vpfe_dev->v4l2_dev);
 422        if (ret)
 423                return ret;
 424
 425        ret = vpfe_ipipeif_register_entities(&vpfe_dev->vpfe_ipipeif,
 426                                             &vpfe_dev->v4l2_dev);
 427        if (ret)
 428                goto out_isif_register;
 429
 430        ret = vpfe_ipipe_register_entities(&vpfe_dev->vpfe_ipipe,
 431                                           &vpfe_dev->v4l2_dev);
 432        if (ret)
 433                goto out_ipipeif_register;
 434
 435        ret = vpfe_resizer_register_entities(&vpfe_dev->vpfe_resizer,
 436                                             &vpfe_dev->v4l2_dev);
 437        if (ret)
 438                goto out_ipipe_register;
 439
 440        /* create links now, starting with external(i2c) entities */
 441        for (i = 0; i < vpfe_dev->num_ext_subdevs; i++)
 442                /*
 443                 * if entity has no pads (ex: amplifier),
 444                 * can't establish link
 445                 */
 446                if (vpfe_dev->sd[i]->entity.num_pads) {
 447                        ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
 448                                0, &vpfe_dev->vpfe_isif.subdev.entity,
 449                                0, flags);
 450                        if (ret < 0)
 451                                goto out_resizer_register;
 452                }
 453
 454        ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
 455                                       &vpfe_dev->vpfe_ipipeif.subdev.entity,
 456                                       0, flags);
 457        if (ret < 0)
 458                goto out_resizer_register;
 459
 460        ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 461                                       &vpfe_dev->vpfe_ipipe.subdev.entity,
 462                                       0, flags);
 463        if (ret < 0)
 464                goto out_resizer_register;
 465
 466        ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
 467                        1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 468                        0, flags);
 469        if (ret < 0)
 470                goto out_resizer_register;
 471
 472        ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 473                        &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 474                        0, flags);
 475        if (ret < 0)
 476                goto out_resizer_register;
 477
 478        ret = v4l2_device_register_subdev_nodes(&vpfe_dev->v4l2_dev);
 479        if (ret < 0)
 480                goto out_resizer_register;
 481
 482        return 0;
 483
 484out_resizer_register:
 485        vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
 486out_ipipe_register:
 487        vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
 488out_ipipeif_register:
 489        vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
 490out_isif_register:
 491        vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
 492
 493        return ret;
 494}
 495
 496/*
 497 * vpfe_unregister_entities() - unregister all v4l2 subdevs and media entities
 498 * @vpfe_dev - ptr to vpfe capture device
 499 *
 500 * unregister all v4l2 subdevs and media entities
 501 */
 502static void vpfe_unregister_entities(struct vpfe_device *vpfe_dev)
 503{
 504        vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
 505        vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
 506        vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
 507        vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
 508}
 509
 510/*
 511 * vpfe_cleanup_modules() - cleanup all non-i2c v4l2 subdevs
 512 * @vpfe_dev - ptr to vpfe capture device
 513 * @pdev - pointer to platform device
 514 *
 515 * cleanup all v4l2 subdevs
 516 */
 517static void vpfe_cleanup_modules(struct vpfe_device *vpfe_dev,
 518                                 struct platform_device *pdev)
 519{
 520        vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
 521        vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
 522        vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
 523        vpfe_resizer_cleanup(&vpfe_dev->vpfe_resizer, pdev);
 524}
 525
 526/*
 527 * vpfe_initialize_modules() - initialize all non-i2c v4l2 subdevs
 528 * @vpfe_dev - ptr to vpfe capture device
 529 * @pdev - pointer to platform device
 530 *
 531 * initialize all v4l2 subdevs and media entities
 532 */
 533static int vpfe_initialize_modules(struct vpfe_device *vpfe_dev,
 534                                   struct platform_device *pdev)
 535{
 536        int ret;
 537
 538        ret = vpfe_isif_init(&vpfe_dev->vpfe_isif, pdev);
 539        if (ret)
 540                return ret;
 541
 542        ret = vpfe_ipipeif_init(&vpfe_dev->vpfe_ipipeif, pdev);
 543        if (ret)
 544                goto out_isif_init;
 545
 546        ret = vpfe_ipipe_init(&vpfe_dev->vpfe_ipipe, pdev);
 547        if (ret)
 548                goto out_ipipeif_init;
 549
 550        ret = vpfe_resizer_init(&vpfe_dev->vpfe_resizer, pdev);
 551        if (ret)
 552                goto out_ipipe_init;
 553
 554        return 0;
 555
 556out_ipipe_init:
 557        vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
 558out_ipipeif_init:
 559        vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
 560out_isif_init:
 561        vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
 562
 563        return ret;
 564}
 565
 566/*
 567 * vpfe_probe() : vpfe probe function
 568 * @pdev: platform device pointer
 569 *
 570 * This function creates device entries by register itself to the V4L2 driver
 571 * and initializes fields of each device objects
 572 */
 573static int vpfe_probe(struct platform_device *pdev)
 574{
 575        struct vpfe_device *vpfe_dev;
 576        struct resource *res1;
 577        int ret = -ENOMEM;
 578
 579        vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
 580        if (!vpfe_dev)
 581                return ret;
 582
 583        if (pdev->dev.platform_data == NULL) {
 584                v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
 585                ret = -ENOENT;
 586                goto probe_free_dev_mem;
 587        }
 588
 589        vpfe_dev->cfg = pdev->dev.platform_data;
 590        if (vpfe_dev->cfg->card_name == NULL ||
 591                        vpfe_dev->cfg->sub_devs == NULL) {
 592                v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
 593                ret = -ENOENT;
 594                goto probe_free_dev_mem;
 595        }
 596
 597        /* Get VINT0 irq resource */
 598        res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 599        if (!res1) {
 600                v4l2_err(pdev->dev.driver,
 601                         "Unable to get interrupt for VINT0\n");
 602                ret = -ENOENT;
 603                goto probe_free_dev_mem;
 604        }
 605        vpfe_dev->ccdc_irq0 = res1->start;
 606
 607        /* Get VINT1 irq resource */
 608        res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
 609        if (!res1) {
 610                v4l2_err(pdev->dev.driver,
 611                         "Unable to get interrupt for VINT1\n");
 612                ret = -ENOENT;
 613                goto probe_free_dev_mem;
 614        }
 615        vpfe_dev->ccdc_irq1 = res1->start;
 616
 617        /* Get DMA irq resource */
 618        res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
 619        if (!res1) {
 620                v4l2_err(pdev->dev.driver,
 621                         "Unable to get interrupt for DMA\n");
 622                ret = -ENOENT;
 623                goto probe_free_dev_mem;
 624        }
 625        vpfe_dev->imp_dma_irq = res1->start;
 626
 627        vpfe_dev->pdev = &pdev->dev;
 628
 629        /* enable vpss clocks */
 630        ret = vpfe_enable_clock(vpfe_dev);
 631        if (ret)
 632                goto probe_free_dev_mem;
 633
 634        ret = vpfe_initialize_modules(vpfe_dev, pdev);
 635        if (ret)
 636                goto probe_disable_clock;
 637
 638        vpfe_dev->media_dev.dev = vpfe_dev->pdev;
 639        strscpy((char *)&vpfe_dev->media_dev.model, "davinci-media",
 640                sizeof(vpfe_dev->media_dev.model));
 641
 642        ret = media_device_register(&vpfe_dev->media_dev);
 643        if (ret) {
 644                v4l2_err(pdev->dev.driver,
 645                        "Unable to register media device.\n");
 646                goto probe_out_entities_cleanup;
 647        }
 648
 649        vpfe_dev->v4l2_dev.mdev = &vpfe_dev->media_dev;
 650        ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
 651        if (ret) {
 652                v4l2_err(pdev->dev.driver, "Unable to register v4l2 device.\n");
 653                goto probe_out_media_unregister;
 654        }
 655
 656        v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
 657        /* set the driver data in platform device */
 658        platform_set_drvdata(pdev, vpfe_dev);
 659        /* register subdevs/entities */
 660        ret = vpfe_register_entities(vpfe_dev);
 661        if (ret)
 662                goto probe_out_v4l2_unregister;
 663
 664        ret = vpfe_attach_irq(vpfe_dev);
 665        if (ret)
 666                goto probe_out_entities_unregister;
 667
 668        return 0;
 669
 670probe_out_entities_unregister:
 671        vpfe_unregister_entities(vpfe_dev);
 672        kzfree(vpfe_dev->sd);
 673probe_out_v4l2_unregister:
 674        v4l2_device_unregister(&vpfe_dev->v4l2_dev);
 675probe_out_media_unregister:
 676        media_device_unregister(&vpfe_dev->media_dev);
 677probe_out_entities_cleanup:
 678        vpfe_cleanup_modules(vpfe_dev, pdev);
 679probe_disable_clock:
 680        vpfe_disable_clock(vpfe_dev);
 681probe_free_dev_mem:
 682        kzfree(vpfe_dev);
 683
 684        return ret;
 685}
 686
 687/*
 688 * vpfe_remove : This function un-registers device from V4L2 driver
 689 */
 690static int vpfe_remove(struct platform_device *pdev)
 691{
 692        struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
 693
 694        v4l2_info(pdev->dev.driver, "%s\n", __func__);
 695
 696        kzfree(vpfe_dev->sd);
 697        vpfe_detach_irq(vpfe_dev);
 698        vpfe_unregister_entities(vpfe_dev);
 699        vpfe_cleanup_modules(vpfe_dev, pdev);
 700        v4l2_device_unregister(&vpfe_dev->v4l2_dev);
 701        media_device_unregister(&vpfe_dev->media_dev);
 702        vpfe_disable_clock(vpfe_dev);
 703        kzfree(vpfe_dev);
 704
 705        return 0;
 706}
 707
 708static struct platform_driver vpfe_driver = {
 709        .driver = {
 710                .name = CAPTURE_DRV_NAME,
 711        },
 712        .probe = vpfe_probe,
 713        .remove = vpfe_remove,
 714};
 715
 716module_platform_driver(vpfe_driver);
 717