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