linux/drivers/media/platform/davinci/vpif_capture.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2009 Texas Instruments Inc
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; either version 2 of the License, or
   7 * (at your option) any later version.
   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 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write to the Free Software
  16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  17 *
  18 * TODO : add support for VBI & HBI data service
  19 *        add static buffer allocation
  20 */
  21
  22#include <linux/module.h>
  23#include <linux/interrupt.h>
  24#include <linux/platform_device.h>
  25#include <linux/slab.h>
  26
  27#include <media/v4l2-ioctl.h>
  28
  29#include "vpif.h"
  30#include "vpif_capture.h"
  31
  32MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
  33MODULE_LICENSE("GPL");
  34MODULE_VERSION(VPIF_CAPTURE_VERSION);
  35
  36#define vpif_err(fmt, arg...)   v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
  37#define vpif_dbg(level, debug, fmt, arg...)     \
  38                v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
  39
  40static int debug = 1;
  41static u32 ch0_numbuffers = 3;
  42static u32 ch1_numbuffers = 3;
  43static u32 ch0_bufsize = 1920 * 1080 * 2;
  44static u32 ch1_bufsize = 720 * 576 * 2;
  45
  46module_param(debug, int, 0644);
  47module_param(ch0_numbuffers, uint, S_IRUGO);
  48module_param(ch1_numbuffers, uint, S_IRUGO);
  49module_param(ch0_bufsize, uint, S_IRUGO);
  50module_param(ch1_bufsize, uint, S_IRUGO);
  51
  52MODULE_PARM_DESC(debug, "Debug level 0-1");
  53MODULE_PARM_DESC(ch2_numbuffers, "Channel0 buffer count (default:3)");
  54MODULE_PARM_DESC(ch3_numbuffers, "Channel1 buffer count (default:3)");
  55MODULE_PARM_DESC(ch2_bufsize, "Channel0 buffer size (default:1920 x 1080 x 2)");
  56MODULE_PARM_DESC(ch3_bufsize, "Channel1 buffer size (default:720 x 576 x 2)");
  57
  58static struct vpif_config_params config_params = {
  59        .min_numbuffers = 3,
  60        .numbuffers[0] = 3,
  61        .numbuffers[1] = 3,
  62        .min_bufsize[0] = 720 * 480 * 2,
  63        .min_bufsize[1] = 720 * 480 * 2,
  64        .channel_bufsize[0] = 1920 * 1080 * 2,
  65        .channel_bufsize[1] = 720 * 576 * 2,
  66};
  67
  68/* global variables */
  69static struct vpif_device vpif_obj = { {NULL} };
  70static struct device *vpif_dev;
  71static void vpif_calculate_offsets(struct channel_obj *ch);
  72static void vpif_config_addr(struct channel_obj *ch, int muxmode);
  73
  74/**
  75 * buffer_prepare :  callback function for buffer prepare
  76 * @vb: ptr to vb2_buffer
  77 *
  78 * This is the callback function for buffer prepare when vb2_qbuf()
  79 * function is called. The buffer is prepared and user space virtual address
  80 * or user address is converted into  physical address
  81 */
  82static int vpif_buffer_prepare(struct vb2_buffer *vb)
  83{
  84        /* Get the file handle object and channel object */
  85        struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
  86        struct vb2_queue *q = vb->vb2_queue;
  87        struct channel_obj *ch = fh->channel;
  88        struct common_obj *common;
  89        unsigned long addr;
  90
  91        vpif_dbg(2, debug, "vpif_buffer_prepare\n");
  92
  93        common = &ch->common[VPIF_VIDEO_INDEX];
  94
  95        if (vb->state != VB2_BUF_STATE_ACTIVE &&
  96                vb->state != VB2_BUF_STATE_PREPARED) {
  97                vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
  98                if (vb2_plane_vaddr(vb, 0) &&
  99                vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
 100                        goto exit;
 101                addr = vb2_dma_contig_plane_dma_addr(vb, 0);
 102
 103                if (q->streaming) {
 104                        if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
 105                                !IS_ALIGNED((addr + common->ybtm_off), 8) ||
 106                                !IS_ALIGNED((addr + common->ctop_off), 8) ||
 107                                !IS_ALIGNED((addr + common->cbtm_off), 8))
 108                                goto exit;
 109                }
 110        }
 111        return 0;
 112exit:
 113        vpif_dbg(1, debug, "buffer_prepare:offset is not aligned to 8 bytes\n");
 114        return -EINVAL;
 115}
 116
 117/**
 118 * vpif_buffer_queue_setup : Callback function for buffer setup.
 119 * @vq: vb2_queue ptr
 120 * @fmt: v4l2 format
 121 * @nbuffers: ptr to number of buffers requested by application
 122 * @nplanes:: contains number of distinct video planes needed to hold a frame
 123 * @sizes[]: contains the size (in bytes) of each plane.
 124 * @alloc_ctxs: ptr to allocation context
 125 *
 126 * This callback function is called when reqbuf() is called to adjust
 127 * the buffer count and buffer size
 128 */
 129static int vpif_buffer_queue_setup(struct vb2_queue *vq,
 130                                const struct v4l2_format *fmt,
 131                                unsigned int *nbuffers, unsigned int *nplanes,
 132                                unsigned int sizes[], void *alloc_ctxs[])
 133{
 134        /* Get the file handle object and channel object */
 135        struct vpif_fh *fh = vb2_get_drv_priv(vq);
 136        struct channel_obj *ch = fh->channel;
 137        struct common_obj *common;
 138        unsigned long size;
 139
 140        common = &ch->common[VPIF_VIDEO_INDEX];
 141
 142        vpif_dbg(2, debug, "vpif_buffer_setup\n");
 143
 144        /* If memory type is not mmap, return */
 145        if (V4L2_MEMORY_MMAP == common->memory) {
 146                /* Calculate the size of the buffer */
 147                size = config_params.channel_bufsize[ch->channel_id];
 148                /*
 149                 * Checking if the buffer size exceeds the available buffer
 150                 * ycmux_mode = 0 means 1 channel mode HD and
 151                 * ycmux_mode = 1 means 2 channels mode SD
 152                 */
 153                if (ch->vpifparams.std_info.ycmux_mode == 0) {
 154                        if (config_params.video_limit[ch->channel_id])
 155                                while (size * *nbuffers >
 156                                        (config_params.video_limit[0]
 157                                                + config_params.video_limit[1]))
 158                                        (*nbuffers)--;
 159                } else {
 160                        if (config_params.video_limit[ch->channel_id])
 161                                while (size * *nbuffers >
 162                                config_params.video_limit[ch->channel_id])
 163                                        (*nbuffers)--;
 164                }
 165
 166        } else {
 167                size = common->fmt.fmt.pix.sizeimage;
 168        }
 169
 170        if (*nbuffers < config_params.min_numbuffers)
 171                *nbuffers = config_params.min_numbuffers;
 172
 173        *nplanes = 1;
 174        sizes[0] = size;
 175        alloc_ctxs[0] = common->alloc_ctx;
 176
 177        return 0;
 178}
 179
 180/**
 181 * vpif_buffer_queue : Callback function to add buffer to DMA queue
 182 * @vb: ptr to vb2_buffer
 183 */
 184static void vpif_buffer_queue(struct vb2_buffer *vb)
 185{
 186        /* Get the file handle object and channel object */
 187        struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
 188        struct channel_obj *ch = fh->channel;
 189        struct vpif_cap_buffer *buf = container_of(vb,
 190                                struct vpif_cap_buffer, vb);
 191        struct common_obj *common;
 192        unsigned long flags;
 193
 194        common = &ch->common[VPIF_VIDEO_INDEX];
 195
 196        vpif_dbg(2, debug, "vpif_buffer_queue\n");
 197
 198        spin_lock_irqsave(&common->irqlock, flags);
 199        /* add the buffer to the DMA queue */
 200        list_add_tail(&buf->list, &common->dma_queue);
 201        spin_unlock_irqrestore(&common->irqlock, flags);
 202}
 203
 204/**
 205 * vpif_buf_cleanup : Callback function to free buffer
 206 * @vb: ptr to vb2_buffer
 207 *
 208 * This function is called from the videobuf2 layer to free memory
 209 * allocated to  the buffers
 210 */
 211static void vpif_buf_cleanup(struct vb2_buffer *vb)
 212{
 213        /* Get the file handle object and channel object */
 214        struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
 215        struct vpif_cap_buffer *buf = container_of(vb,
 216                                        struct vpif_cap_buffer, vb);
 217        struct channel_obj *ch = fh->channel;
 218        struct common_obj *common;
 219        unsigned long flags;
 220
 221        common = &ch->common[VPIF_VIDEO_INDEX];
 222
 223        spin_lock_irqsave(&common->irqlock, flags);
 224        if (vb->state == VB2_BUF_STATE_ACTIVE)
 225                list_del_init(&buf->list);
 226        spin_unlock_irqrestore(&common->irqlock, flags);
 227
 228}
 229
 230static void vpif_wait_prepare(struct vb2_queue *vq)
 231{
 232        struct vpif_fh *fh = vb2_get_drv_priv(vq);
 233        struct channel_obj *ch = fh->channel;
 234        struct common_obj *common;
 235
 236        common = &ch->common[VPIF_VIDEO_INDEX];
 237        mutex_unlock(&common->lock);
 238}
 239
 240static void vpif_wait_finish(struct vb2_queue *vq)
 241{
 242        struct vpif_fh *fh = vb2_get_drv_priv(vq);
 243        struct channel_obj *ch = fh->channel;
 244        struct common_obj *common;
 245
 246        common = &ch->common[VPIF_VIDEO_INDEX];
 247        mutex_lock(&common->lock);
 248}
 249
 250static int vpif_buffer_init(struct vb2_buffer *vb)
 251{
 252        struct vpif_cap_buffer *buf = container_of(vb,
 253                                        struct vpif_cap_buffer, vb);
 254
 255        INIT_LIST_HEAD(&buf->list);
 256
 257        return 0;
 258}
 259
 260static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
 261        { {1, 1} };
 262
 263static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 264{
 265        struct vpif_capture_config *vpif_config_data =
 266                                        vpif_dev->platform_data;
 267        struct vpif_fh *fh = vb2_get_drv_priv(vq);
 268        struct channel_obj *ch = fh->channel;
 269        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 270        struct vpif_params *vpif = &ch->vpifparams;
 271        unsigned long addr = 0;
 272        unsigned long flags;
 273        int ret;
 274
 275        /* If buffer queue is empty, return error */
 276        spin_lock_irqsave(&common->irqlock, flags);
 277        if (list_empty(&common->dma_queue)) {
 278                spin_unlock_irqrestore(&common->irqlock, flags);
 279                vpif_dbg(1, debug, "buffer queue is empty\n");
 280                return -EIO;
 281        }
 282
 283        /* Get the next frame from the buffer queue */
 284        common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
 285                                    struct vpif_cap_buffer, list);
 286        /* Remove buffer from the buffer queue */
 287        list_del(&common->cur_frm->list);
 288        spin_unlock_irqrestore(&common->irqlock, flags);
 289        /* Mark state of the current frame to active */
 290        common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
 291        /* Initialize field_id and started member */
 292        ch->field_id = 0;
 293        common->started = 1;
 294        addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
 295
 296        /* Calculate the offset for Y and C data in the buffer */
 297        vpif_calculate_offsets(ch);
 298
 299        if ((vpif->std_info.frm_fmt &&
 300            ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) &&
 301             (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) ||
 302            (!vpif->std_info.frm_fmt &&
 303             (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
 304                vpif_dbg(1, debug, "conflict in field format and std format\n");
 305                return -EINVAL;
 306        }
 307
 308        /* configure 1 or 2 channel mode */
 309        if (vpif_config_data->setup_input_channel_mode) {
 310                ret = vpif_config_data->
 311                        setup_input_channel_mode(vpif->std_info.ycmux_mode);
 312                if (ret < 0) {
 313                        vpif_dbg(1, debug, "can't set vpif channel mode\n");
 314                        return ret;
 315                }
 316        }
 317
 318        /* Call vpif_set_params function to set the parameters and addresses */
 319        ret = vpif_set_video_params(vpif, ch->channel_id);
 320
 321        if (ret < 0) {
 322                vpif_dbg(1, debug, "can't set video params\n");
 323                return ret;
 324        }
 325
 326        common->started = ret;
 327        vpif_config_addr(ch, ret);
 328
 329        common->set_addr(addr + common->ytop_off,
 330                         addr + common->ybtm_off,
 331                         addr + common->ctop_off,
 332                         addr + common->cbtm_off);
 333
 334        /**
 335         * Set interrupt for both the fields in VPIF Register enable channel in
 336         * VPIF register
 337         */
 338        channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
 339        if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
 340                channel0_intr_assert();
 341                channel0_intr_enable(1);
 342                enable_channel0(1);
 343        }
 344        if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
 345            (common->started == 2)) {
 346                channel1_intr_assert();
 347                channel1_intr_enable(1);
 348                enable_channel1(1);
 349        }
 350
 351        return 0;
 352}
 353
 354/* abort streaming and wait for last buffer */
 355static int vpif_stop_streaming(struct vb2_queue *vq)
 356{
 357        struct vpif_fh *fh = vb2_get_drv_priv(vq);
 358        struct channel_obj *ch = fh->channel;
 359        struct common_obj *common;
 360        unsigned long flags;
 361
 362        if (!vb2_is_streaming(vq))
 363                return 0;
 364
 365        common = &ch->common[VPIF_VIDEO_INDEX];
 366
 367        /* release all active buffers */
 368        spin_lock_irqsave(&common->irqlock, flags);
 369        while (!list_empty(&common->dma_queue)) {
 370                common->next_frm = list_entry(common->dma_queue.next,
 371                                                struct vpif_cap_buffer, list);
 372                list_del(&common->next_frm->list);
 373                vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
 374        }
 375        spin_unlock_irqrestore(&common->irqlock, flags);
 376
 377        return 0;
 378}
 379
 380static struct vb2_ops video_qops = {
 381        .queue_setup            = vpif_buffer_queue_setup,
 382        .wait_prepare           = vpif_wait_prepare,
 383        .wait_finish            = vpif_wait_finish,
 384        .buf_init               = vpif_buffer_init,
 385        .buf_prepare            = vpif_buffer_prepare,
 386        .start_streaming        = vpif_start_streaming,
 387        .stop_streaming         = vpif_stop_streaming,
 388        .buf_cleanup            = vpif_buf_cleanup,
 389        .buf_queue              = vpif_buffer_queue,
 390};
 391
 392/**
 393 * vpif_process_buffer_complete: process a completed buffer
 394 * @common: ptr to common channel object
 395 *
 396 * This function time stamp the buffer and mark it as DONE. It also
 397 * wake up any process waiting on the QUEUE and set the next buffer
 398 * as current
 399 */
 400static void vpif_process_buffer_complete(struct common_obj *common)
 401{
 402        v4l2_get_timestamp(&common->cur_frm->vb.v4l2_buf.timestamp);
 403        vb2_buffer_done(&common->cur_frm->vb,
 404                                            VB2_BUF_STATE_DONE);
 405        /* Make curFrm pointing to nextFrm */
 406        common->cur_frm = common->next_frm;
 407}
 408
 409/**
 410 * vpif_schedule_next_buffer: set next buffer address for capture
 411 * @common : ptr to common channel object
 412 *
 413 * This function will get next buffer from the dma queue and
 414 * set the buffer address in the vpif register for capture.
 415 * the buffer is marked active
 416 */
 417static void vpif_schedule_next_buffer(struct common_obj *common)
 418{
 419        unsigned long addr = 0;
 420
 421        spin_lock(&common->irqlock);
 422        common->next_frm = list_entry(common->dma_queue.next,
 423                                     struct vpif_cap_buffer, list);
 424        /* Remove that buffer from the buffer queue */
 425        list_del(&common->next_frm->list);
 426        spin_unlock(&common->irqlock);
 427        common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE;
 428        addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb, 0);
 429
 430        /* Set top and bottom field addresses in VPIF registers */
 431        common->set_addr(addr + common->ytop_off,
 432                         addr + common->ybtm_off,
 433                         addr + common->ctop_off,
 434                         addr + common->cbtm_off);
 435}
 436
 437/**
 438 * vpif_channel_isr : ISR handler for vpif capture
 439 * @irq: irq number
 440 * @dev_id: dev_id ptr
 441 *
 442 * It changes status of the captured buffer, takes next buffer from the queue
 443 * and sets its address in VPIF registers
 444 */
 445static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
 446{
 447        struct vpif_device *dev = &vpif_obj;
 448        struct common_obj *common;
 449        struct channel_obj *ch;
 450        enum v4l2_field field;
 451        int channel_id = 0;
 452        int fid = -1, i;
 453
 454        channel_id = *(int *)(dev_id);
 455        if (!vpif_intr_status(channel_id))
 456                return IRQ_NONE;
 457
 458        ch = dev->dev[channel_id];
 459
 460        field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
 461
 462        for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
 463                common = &ch->common[i];
 464                /* skip If streaming is not started in this channel */
 465                if (0 == common->started)
 466                        continue;
 467
 468                /* Check the field format */
 469                if (1 == ch->vpifparams.std_info.frm_fmt) {
 470                        /* Progressive mode */
 471                        spin_lock(&common->irqlock);
 472                        if (list_empty(&common->dma_queue)) {
 473                                spin_unlock(&common->irqlock);
 474                                continue;
 475                        }
 476                        spin_unlock(&common->irqlock);
 477
 478                        if (!channel_first_int[i][channel_id])
 479                                vpif_process_buffer_complete(common);
 480
 481                        channel_first_int[i][channel_id] = 0;
 482
 483                        vpif_schedule_next_buffer(common);
 484
 485
 486                        channel_first_int[i][channel_id] = 0;
 487                } else {
 488                        /**
 489                         * Interlaced mode. If it is first interrupt, ignore
 490                         * it
 491                         */
 492                        if (channel_first_int[i][channel_id]) {
 493                                channel_first_int[i][channel_id] = 0;
 494                                continue;
 495                        }
 496                        if (0 == i) {
 497                                ch->field_id ^= 1;
 498                                /* Get field id from VPIF registers */
 499                                fid = vpif_channel_getfid(ch->channel_id);
 500                                if (fid != ch->field_id) {
 501                                        /**
 502                                         * If field id does not match stored
 503                                         * field id, make them in sync
 504                                         */
 505                                        if (0 == fid)
 506                                                ch->field_id = fid;
 507                                        return IRQ_HANDLED;
 508                                }
 509                        }
 510                        /* device field id and local field id are in sync */
 511                        if (0 == fid) {
 512                                /* this is even field */
 513                                if (common->cur_frm == common->next_frm)
 514                                        continue;
 515
 516                                /* mark the current buffer as done */
 517                                vpif_process_buffer_complete(common);
 518                        } else if (1 == fid) {
 519                                /* odd field */
 520                                spin_lock(&common->irqlock);
 521                                if (list_empty(&common->dma_queue) ||
 522                                    (common->cur_frm != common->next_frm)) {
 523                                        spin_unlock(&common->irqlock);
 524                                        continue;
 525                                }
 526                                spin_unlock(&common->irqlock);
 527
 528                                vpif_schedule_next_buffer(common);
 529                        }
 530                }
 531        }
 532        return IRQ_HANDLED;
 533}
 534
 535/**
 536 * vpif_update_std_info() - update standard related info
 537 * @ch: ptr to channel object
 538 *
 539 * For a given standard selected by application, update values
 540 * in the device data structures
 541 */
 542static int vpif_update_std_info(struct channel_obj *ch)
 543{
 544        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 545        struct vpif_params *vpifparams = &ch->vpifparams;
 546        const struct vpif_channel_config_params *config;
 547        struct vpif_channel_config_params *std_info = &vpifparams->std_info;
 548        struct video_obj *vid_ch = &ch->video;
 549        int index;
 550
 551        vpif_dbg(2, debug, "vpif_update_std_info\n");
 552
 553        for (index = 0; index < vpif_ch_params_count; index++) {
 554                config = &vpif_ch_params[index];
 555                if (config->hd_sd == 0) {
 556                        vpif_dbg(2, debug, "SD format\n");
 557                        if (config->stdid & vid_ch->stdid) {
 558                                memcpy(std_info, config, sizeof(*config));
 559                                break;
 560                        }
 561                } else {
 562                        vpif_dbg(2, debug, "HD format\n");
 563                        if (!memcmp(&config->dv_timings, &vid_ch->dv_timings,
 564                                sizeof(vid_ch->dv_timings))) {
 565                                memcpy(std_info, config, sizeof(*config));
 566                                break;
 567                        }
 568                }
 569        }
 570
 571        /* standard not found */
 572        if (index == vpif_ch_params_count)
 573                return -EINVAL;
 574
 575        common->fmt.fmt.pix.width = std_info->width;
 576        common->width = std_info->width;
 577        common->fmt.fmt.pix.height = std_info->height;
 578        common->height = std_info->height;
 579        common->fmt.fmt.pix.bytesperline = std_info->width;
 580        vpifparams->video_params.hpitch = std_info->width;
 581        vpifparams->video_params.storage_mode = std_info->frm_fmt;
 582
 583        return 0;
 584}
 585
 586/**
 587 * vpif_calculate_offsets : This function calculates buffers offsets
 588 * @ch : ptr to channel object
 589 *
 590 * This function calculates buffer offsets for Y and C in the top and
 591 * bottom field
 592 */
 593static void vpif_calculate_offsets(struct channel_obj *ch)
 594{
 595        unsigned int hpitch, vpitch, sizeimage;
 596        struct video_obj *vid_ch = &(ch->video);
 597        struct vpif_params *vpifparams = &ch->vpifparams;
 598        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 599        enum v4l2_field field = common->fmt.fmt.pix.field;
 600
 601        vpif_dbg(2, debug, "vpif_calculate_offsets\n");
 602
 603        if (V4L2_FIELD_ANY == field) {
 604                if (vpifparams->std_info.frm_fmt)
 605                        vid_ch->buf_field = V4L2_FIELD_NONE;
 606                else
 607                        vid_ch->buf_field = V4L2_FIELD_INTERLACED;
 608        } else
 609                vid_ch->buf_field = common->fmt.fmt.pix.field;
 610
 611        sizeimage = common->fmt.fmt.pix.sizeimage;
 612
 613        hpitch = common->fmt.fmt.pix.bytesperline;
 614        vpitch = sizeimage / (hpitch * 2);
 615
 616        if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
 617            (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
 618                /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
 619                common->ytop_off = 0;
 620                common->ybtm_off = hpitch;
 621                common->ctop_off = sizeimage / 2;
 622                common->cbtm_off = sizeimage / 2 + hpitch;
 623        } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
 624                /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
 625                common->ytop_off = 0;
 626                common->ybtm_off = sizeimage / 4;
 627                common->ctop_off = sizeimage / 2;
 628                common->cbtm_off = common->ctop_off + sizeimage / 4;
 629        } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
 630                /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
 631                common->ybtm_off = 0;
 632                common->ytop_off = sizeimage / 4;
 633                common->cbtm_off = sizeimage / 2;
 634                common->ctop_off = common->cbtm_off + sizeimage / 4;
 635        }
 636        if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
 637            (V4L2_FIELD_INTERLACED == vid_ch->buf_field))
 638                vpifparams->video_params.storage_mode = 1;
 639        else
 640                vpifparams->video_params.storage_mode = 0;
 641
 642        if (1 == vpifparams->std_info.frm_fmt)
 643                vpifparams->video_params.hpitch =
 644                    common->fmt.fmt.pix.bytesperline;
 645        else {
 646                if ((field == V4L2_FIELD_ANY)
 647                    || (field == V4L2_FIELD_INTERLACED))
 648                        vpifparams->video_params.hpitch =
 649                            common->fmt.fmt.pix.bytesperline * 2;
 650                else
 651                        vpifparams->video_params.hpitch =
 652                            common->fmt.fmt.pix.bytesperline;
 653        }
 654
 655        ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
 656}
 657
 658/**
 659 * vpif_config_format: configure default frame format in the device
 660 * ch : ptr to channel object
 661 */
 662static void vpif_config_format(struct channel_obj *ch)
 663{
 664        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 665
 666        vpif_dbg(2, debug, "vpif_config_format\n");
 667
 668        common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
 669        if (config_params.numbuffers[ch->channel_id] == 0)
 670                common->memory = V4L2_MEMORY_USERPTR;
 671        else
 672                common->memory = V4L2_MEMORY_MMAP;
 673
 674        common->fmt.fmt.pix.sizeimage
 675            = config_params.channel_bufsize[ch->channel_id];
 676
 677        if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
 678                common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
 679        else
 680                common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
 681        common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 682}
 683
 684/**
 685 * vpif_get_default_field() - Get default field type based on interface
 686 * @vpif_params - ptr to vpif params
 687 */
 688static inline enum v4l2_field vpif_get_default_field(
 689                                struct vpif_interface *iface)
 690{
 691        return (iface->if_type == VPIF_IF_RAW_BAYER) ? V4L2_FIELD_NONE :
 692                                                V4L2_FIELD_INTERLACED;
 693}
 694
 695/**
 696 * vpif_check_format()  - check given pixel format for compatibility
 697 * @ch - channel  ptr
 698 * @pixfmt - Given pixel format
 699 * @update - update the values as per hardware requirement
 700 *
 701 * Check the application pixel format for S_FMT and update the input
 702 * values as per hardware limits for TRY_FMT. The default pixel and
 703 * field format is selected based on interface type.
 704 */
 705static int vpif_check_format(struct channel_obj *ch,
 706                             struct v4l2_pix_format *pixfmt,
 707                             int update)
 708{
 709        struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
 710        struct vpif_params *vpif_params = &ch->vpifparams;
 711        enum v4l2_field field = pixfmt->field;
 712        u32 sizeimage, hpitch, vpitch;
 713        int ret = -EINVAL;
 714
 715        vpif_dbg(2, debug, "vpif_check_format\n");
 716        /**
 717         * first check for the pixel format. If if_type is Raw bayer,
 718         * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
 719         * V4L2_PIX_FMT_YUV422P is supported
 720         */
 721        if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
 722                if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
 723                        if (!update) {
 724                                vpif_dbg(2, debug, "invalid pix format\n");
 725                                goto exit;
 726                        }
 727                        pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
 728                }
 729        } else {
 730                if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
 731                        if (!update) {
 732                                vpif_dbg(2, debug, "invalid pixel format\n");
 733                                goto exit;
 734                        }
 735                        pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
 736                }
 737        }
 738
 739        if (!(VPIF_VALID_FIELD(field))) {
 740                if (!update) {
 741                        vpif_dbg(2, debug, "invalid field format\n");
 742                        goto exit;
 743                }
 744                /**
 745                 * By default use FIELD_NONE for RAW Bayer capture
 746                 * and FIELD_INTERLACED for other interfaces
 747                 */
 748                field = vpif_get_default_field(&vpif_params->iface);
 749        } else if (field == V4L2_FIELD_ANY)
 750                /* unsupported field. Use default */
 751                field = vpif_get_default_field(&vpif_params->iface);
 752
 753        /* validate the hpitch */
 754        hpitch = pixfmt->bytesperline;
 755        if (hpitch < vpif_params->std_info.width) {
 756                if (!update) {
 757                        vpif_dbg(2, debug, "invalid hpitch\n");
 758                        goto exit;
 759                }
 760                hpitch = vpif_params->std_info.width;
 761        }
 762
 763        sizeimage = pixfmt->sizeimage;
 764
 765        vpitch = sizeimage / (hpitch * 2);
 766
 767        /* validate the vpitch */
 768        if (vpitch < vpif_params->std_info.height) {
 769                if (!update) {
 770                        vpif_dbg(2, debug, "Invalid vpitch\n");
 771                        goto exit;
 772                }
 773                vpitch = vpif_params->std_info.height;
 774        }
 775
 776        /* Check for 8 byte alignment */
 777        if (!ALIGN(hpitch, 8)) {
 778                if (!update) {
 779                        vpif_dbg(2, debug, "invalid pitch alignment\n");
 780                        goto exit;
 781                }
 782                /* adjust to next 8 byte boundary */
 783                hpitch = (((hpitch + 7) / 8) * 8);
 784        }
 785        /* if update is set, modify the bytesperline and sizeimage */
 786        if (update) {
 787                pixfmt->bytesperline = hpitch;
 788                pixfmt->sizeimage = hpitch * vpitch * 2;
 789        }
 790        /**
 791         * Image width and height is always based on current standard width and
 792         * height
 793         */
 794        pixfmt->width = common->fmt.fmt.pix.width;
 795        pixfmt->height = common->fmt.fmt.pix.height;
 796        return 0;
 797exit:
 798        return ret;
 799}
 800
 801/**
 802 * vpif_config_addr() - function to configure buffer address in vpif
 803 * @ch - channel ptr
 804 * @muxmode - channel mux mode
 805 */
 806static void vpif_config_addr(struct channel_obj *ch, int muxmode)
 807{
 808        struct common_obj *common;
 809
 810        vpif_dbg(2, debug, "vpif_config_addr\n");
 811
 812        common = &(ch->common[VPIF_VIDEO_INDEX]);
 813
 814        if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
 815                common->set_addr = ch1_set_videobuf_addr;
 816        else if (2 == muxmode)
 817                common->set_addr = ch0_set_videobuf_addr_yc_nmux;
 818        else
 819                common->set_addr = ch0_set_videobuf_addr;
 820}
 821
 822/**
 823 * vpif_mmap : It is used to map kernel space buffers into user spaces
 824 * @filep: file pointer
 825 * @vma: ptr to vm_area_struct
 826 */
 827static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
 828{
 829        /* Get the channel object and file handle object */
 830        struct vpif_fh *fh = filep->private_data;
 831        struct channel_obj *ch = fh->channel;
 832        struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
 833        int ret;
 834
 835        vpif_dbg(2, debug, "vpif_mmap\n");
 836
 837        if (mutex_lock_interruptible(&common->lock))
 838                return -ERESTARTSYS;
 839        ret = vb2_mmap(&common->buffer_queue, vma);
 840        mutex_unlock(&common->lock);
 841        return ret;
 842}
 843
 844/**
 845 * vpif_poll: It is used for select/poll system call
 846 * @filep: file pointer
 847 * @wait: poll table to wait
 848 */
 849static unsigned int vpif_poll(struct file *filep, poll_table * wait)
 850{
 851        struct vpif_fh *fh = filep->private_data;
 852        struct channel_obj *channel = fh->channel;
 853        struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);
 854        unsigned int res = 0;
 855
 856        vpif_dbg(2, debug, "vpif_poll\n");
 857
 858        if (common->started) {
 859                mutex_lock(&common->lock);
 860                res = vb2_poll(&common->buffer_queue, filep, wait);
 861                mutex_unlock(&common->lock);
 862        }
 863        return res;
 864}
 865
 866/**
 867 * vpif_open : vpif open handler
 868 * @filep: file ptr
 869 *
 870 * It creates object of file handle structure and stores it in private_data
 871 * member of filepointer
 872 */
 873static int vpif_open(struct file *filep)
 874{
 875        struct video_device *vdev = video_devdata(filep);
 876        struct common_obj *common;
 877        struct video_obj *vid_ch;
 878        struct channel_obj *ch;
 879        struct vpif_fh *fh;
 880
 881        vpif_dbg(2, debug, "vpif_open\n");
 882
 883        ch = video_get_drvdata(vdev);
 884
 885        vid_ch = &ch->video;
 886        common = &ch->common[VPIF_VIDEO_INDEX];
 887
 888        /* Allocate memory for the file handle object */
 889        fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
 890        if (NULL == fh) {
 891                vpif_err("unable to allocate memory for file handle object\n");
 892                return -ENOMEM;
 893        }
 894
 895        if (mutex_lock_interruptible(&common->lock)) {
 896                kfree(fh);
 897                return -ERESTARTSYS;
 898        }
 899        /* store pointer to fh in private_data member of filep */
 900        filep->private_data = fh;
 901        fh->channel = ch;
 902        fh->initialized = 0;
 903        /* If decoder is not initialized. initialize it */
 904        if (!ch->initialized) {
 905                fh->initialized = 1;
 906                ch->initialized = 1;
 907                memset(&(ch->vpifparams), 0, sizeof(struct vpif_params));
 908        }
 909        /* Increment channel usrs counter */
 910        ch->usrs++;
 911        /* Set io_allowed member to false */
 912        fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
 913        /* Initialize priority of this instance to default priority */
 914        fh->prio = V4L2_PRIORITY_UNSET;
 915        v4l2_prio_open(&ch->prio, &fh->prio);
 916        mutex_unlock(&common->lock);
 917        return 0;
 918}
 919
 920/**
 921 * vpif_release : function to clean up file close
 922 * @filep: file pointer
 923 *
 924 * This function deletes buffer queue, frees the buffers and the vpif file
 925 * handle
 926 */
 927static int vpif_release(struct file *filep)
 928{
 929        struct vpif_fh *fh = filep->private_data;
 930        struct channel_obj *ch = fh->channel;
 931        struct common_obj *common;
 932
 933        vpif_dbg(2, debug, "vpif_release\n");
 934
 935        common = &ch->common[VPIF_VIDEO_INDEX];
 936
 937        mutex_lock(&common->lock);
 938        /* if this instance is doing IO */
 939        if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
 940                /* Reset io_usrs member of channel object */
 941                common->io_usrs = 0;
 942                /* Disable channel as per its device type and channel id */
 943                if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
 944                        enable_channel0(0);
 945                        channel0_intr_enable(0);
 946                }
 947                if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
 948                    (2 == common->started)) {
 949                        enable_channel1(0);
 950                        channel1_intr_enable(0);
 951                }
 952                common->started = 0;
 953                /* Free buffers allocated */
 954                vb2_queue_release(&common->buffer_queue);
 955                vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
 956        }
 957
 958        /* Decrement channel usrs counter */
 959        ch->usrs--;
 960
 961        /* Close the priority */
 962        v4l2_prio_close(&ch->prio, fh->prio);
 963
 964        if (fh->initialized)
 965                ch->initialized = 0;
 966
 967        mutex_unlock(&common->lock);
 968        filep->private_data = NULL;
 969        kfree(fh);
 970        return 0;
 971}
 972
 973/**
 974 * vpif_reqbufs() - request buffer handler
 975 * @file: file ptr
 976 * @priv: file handle
 977 * @reqbuf: request buffer structure ptr
 978 */
 979static int vpif_reqbufs(struct file *file, void *priv,
 980                        struct v4l2_requestbuffers *reqbuf)
 981{
 982        struct vpif_fh *fh = priv;
 983        struct channel_obj *ch = fh->channel;
 984        struct common_obj *common;
 985        u8 index = 0;
 986        struct vb2_queue *q;
 987        int ret;
 988
 989        vpif_dbg(2, debug, "vpif_reqbufs\n");
 990
 991        /**
 992         * This file handle has not initialized the channel,
 993         * It is not allowed to do settings
 994         */
 995        if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)
 996            || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
 997                if (!fh->initialized) {
 998                        vpif_dbg(1, debug, "Channel Busy\n");
 999                        return -EBUSY;
1000                }
1001        }
1002
1003        if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type || !vpif_dev)
1004                return -EINVAL;
1005
1006        index = VPIF_VIDEO_INDEX;
1007
1008        common = &ch->common[index];
1009
1010        if (0 != common->io_usrs)
1011                return -EBUSY;
1012
1013        /* Initialize videobuf2 queue as per the buffer type */
1014        common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
1015        if (IS_ERR(common->alloc_ctx)) {
1016                vpif_err("Failed to get the context\n");
1017                return PTR_ERR(common->alloc_ctx);
1018        }
1019        q = &common->buffer_queue;
1020        q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1021        q->io_modes = VB2_MMAP | VB2_USERPTR;
1022        q->drv_priv = fh;
1023        q->ops = &video_qops;
1024        q->mem_ops = &vb2_dma_contig_memops;
1025        q->buf_struct_size = sizeof(struct vpif_cap_buffer);
1026        q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1027
1028        ret = vb2_queue_init(q);
1029        if (ret) {
1030                vpif_err("vpif_capture: vb2_queue_init() failed\n");
1031                vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
1032                return ret;
1033        }
1034        /* Set io allowed member of file handle to TRUE */
1035        fh->io_allowed[index] = 1;
1036        /* Increment io usrs member of channel object to 1 */
1037        common->io_usrs = 1;
1038        /* Store type of memory requested in channel object */
1039        common->memory = reqbuf->memory;
1040        INIT_LIST_HEAD(&common->dma_queue);
1041
1042        /* Allocate buffers */
1043        return vb2_reqbufs(&common->buffer_queue, reqbuf);
1044}
1045
1046/**
1047 * vpif_querybuf() - query buffer handler
1048 * @file: file ptr
1049 * @priv: file handle
1050 * @buf: v4l2 buffer structure ptr
1051 */
1052static int vpif_querybuf(struct file *file, void *priv,
1053                                struct v4l2_buffer *buf)
1054{
1055        struct vpif_fh *fh = priv;
1056        struct channel_obj *ch = fh->channel;
1057        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1058
1059        vpif_dbg(2, debug, "vpif_querybuf\n");
1060
1061        if (common->fmt.type != buf->type)
1062                return -EINVAL;
1063
1064        if (common->memory != V4L2_MEMORY_MMAP) {
1065                vpif_dbg(1, debug, "Invalid memory\n");
1066                return -EINVAL;
1067        }
1068
1069        return vb2_querybuf(&common->buffer_queue, buf);
1070}
1071
1072/**
1073 * vpif_qbuf() - query buffer handler
1074 * @file: file ptr
1075 * @priv: file handle
1076 * @buf: v4l2 buffer structure ptr
1077 */
1078static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1079{
1080
1081        struct vpif_fh *fh = priv;
1082        struct channel_obj *ch = fh->channel;
1083        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1084        struct v4l2_buffer tbuf = *buf;
1085
1086        vpif_dbg(2, debug, "vpif_qbuf\n");
1087
1088        if (common->fmt.type != tbuf.type) {
1089                vpif_err("invalid buffer type\n");
1090                return -EINVAL;
1091        }
1092
1093        if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1094                vpif_err("fh io not allowed\n");
1095                return -EACCES;
1096        }
1097
1098        return vb2_qbuf(&common->buffer_queue, buf);
1099}
1100
1101/**
1102 * vpif_dqbuf() - query buffer handler
1103 * @file: file ptr
1104 * @priv: file handle
1105 * @buf: v4l2 buffer structure ptr
1106 */
1107static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1108{
1109        struct vpif_fh *fh = priv;
1110        struct channel_obj *ch = fh->channel;
1111        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1112
1113        vpif_dbg(2, debug, "vpif_dqbuf\n");
1114
1115        return vb2_dqbuf(&common->buffer_queue, buf,
1116                         (file->f_flags & O_NONBLOCK));
1117}
1118
1119/**
1120 * vpif_streamon() - streamon handler
1121 * @file: file ptr
1122 * @priv: file handle
1123 * @buftype: v4l2 buffer type
1124 */
1125static int vpif_streamon(struct file *file, void *priv,
1126                                enum v4l2_buf_type buftype)
1127{
1128
1129        struct vpif_fh *fh = priv;
1130        struct channel_obj *ch = fh->channel;
1131        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1132        struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
1133        struct vpif_params *vpif;
1134        int ret = 0;
1135
1136        vpif_dbg(2, debug, "vpif_streamon\n");
1137
1138        vpif = &ch->vpifparams;
1139
1140        if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1141                vpif_dbg(1, debug, "buffer type not supported\n");
1142                return -EINVAL;
1143        }
1144
1145        /* If file handle is not allowed IO, return error */
1146        if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1147                vpif_dbg(1, debug, "io not allowed\n");
1148                return -EACCES;
1149        }
1150
1151        /* If Streaming is already started, return error */
1152        if (common->started) {
1153                vpif_dbg(1, debug, "channel->started\n");
1154                return -EBUSY;
1155        }
1156
1157        if ((ch->channel_id == VPIF_CHANNEL0_VIDEO &&
1158            oth_ch->common[VPIF_VIDEO_INDEX].started &&
1159            vpif->std_info.ycmux_mode == 0) ||
1160           ((ch->channel_id == VPIF_CHANNEL1_VIDEO) &&
1161            (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
1162                vpif_dbg(1, debug, "other channel is being used\n");
1163                return -EBUSY;
1164        }
1165
1166        ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0);
1167        if (ret)
1168                return ret;
1169
1170        /* Enable streamon on the sub device */
1171        ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
1172
1173        if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
1174                vpif_dbg(1, debug, "stream on failed in subdev\n");
1175                return ret;
1176        }
1177
1178        /* Call vb2_streamon to start streaming in videobuf2 */
1179        ret = vb2_streamon(&common->buffer_queue, buftype);
1180        if (ret) {
1181                vpif_dbg(1, debug, "vb2_streamon\n");
1182                return ret;
1183        }
1184
1185        return ret;
1186}
1187
1188/**
1189 * vpif_streamoff() - streamoff handler
1190 * @file: file ptr
1191 * @priv: file handle
1192 * @buftype: v4l2 buffer type
1193 */
1194static int vpif_streamoff(struct file *file, void *priv,
1195                                enum v4l2_buf_type buftype)
1196{
1197
1198        struct vpif_fh *fh = priv;
1199        struct channel_obj *ch = fh->channel;
1200        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1201        int ret;
1202
1203        vpif_dbg(2, debug, "vpif_streamoff\n");
1204
1205        if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1206                vpif_dbg(1, debug, "buffer type not supported\n");
1207                return -EINVAL;
1208        }
1209
1210        /* If io is allowed for this file handle, return error */
1211        if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1212                vpif_dbg(1, debug, "io not allowed\n");
1213                return -EACCES;
1214        }
1215
1216        /* If streaming is not started, return error */
1217        if (!common->started) {
1218                vpif_dbg(1, debug, "channel->started\n");
1219                return -EINVAL;
1220        }
1221
1222        /* disable channel */
1223        if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
1224                enable_channel0(0);
1225                channel0_intr_enable(0);
1226        } else {
1227                enable_channel1(0);
1228                channel1_intr_enable(0);
1229        }
1230
1231        common->started = 0;
1232
1233        ret = v4l2_subdev_call(ch->sd, video, s_stream, 0);
1234
1235        if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
1236                vpif_dbg(1, debug, "stream off failed in subdev\n");
1237
1238        return vb2_streamoff(&common->buffer_queue, buftype);
1239}
1240
1241/**
1242 * vpif_input_to_subdev() - Maps input to sub device
1243 * @vpif_cfg - global config ptr
1244 * @chan_cfg - channel config ptr
1245 * @input_index - Given input index from application
1246 *
1247 * lookup the sub device information for a given input index.
1248 * we report all the inputs to application. inputs table also
1249 * has sub device name for the each input
1250 */
1251static int vpif_input_to_subdev(
1252                struct vpif_capture_config *vpif_cfg,
1253                struct vpif_capture_chan_config *chan_cfg,
1254                int input_index)
1255{
1256        struct vpif_subdev_info *subdev_info;
1257        const char *subdev_name;
1258        int i;
1259
1260        vpif_dbg(2, debug, "vpif_input_to_subdev\n");
1261
1262        subdev_name = chan_cfg->inputs[input_index].subdev_name;
1263        if (subdev_name == NULL)
1264                return -1;
1265
1266        /* loop through the sub device list to get the sub device info */
1267        for (i = 0; i < vpif_cfg->subdev_count; i++) {
1268                subdev_info = &vpif_cfg->subdev_info[i];
1269                if (!strcmp(subdev_info->name, subdev_name))
1270                        return i;
1271        }
1272        return -1;
1273}
1274
1275/**
1276 * vpif_set_input() - Select an input
1277 * @vpif_cfg - global config ptr
1278 * @ch - channel
1279 * @_index - Given input index from application
1280 *
1281 * Select the given input.
1282 */
1283static int vpif_set_input(
1284                struct vpif_capture_config *vpif_cfg,
1285                struct channel_obj *ch,
1286                int index)
1287{
1288        struct vpif_capture_chan_config *chan_cfg =
1289                        &vpif_cfg->chan_config[ch->channel_id];
1290        struct vpif_subdev_info *subdev_info = NULL;
1291        struct v4l2_subdev *sd = NULL;
1292        u32 input = 0, output = 0;
1293        int sd_index;
1294        int ret;
1295
1296        sd_index = vpif_input_to_subdev(vpif_cfg, chan_cfg, index);
1297        if (sd_index >= 0) {
1298                sd = vpif_obj.sd[sd_index];
1299                subdev_info = &vpif_cfg->subdev_info[sd_index];
1300        }
1301
1302        /* first setup input path from sub device to vpif */
1303        if (sd && vpif_cfg->setup_input_path) {
1304                ret = vpif_cfg->setup_input_path(ch->channel_id,
1305                                       subdev_info->name);
1306                if (ret < 0) {
1307                        vpif_dbg(1, debug, "couldn't setup input path for the" \
1308                        " sub device %s, for input index %d\n",
1309                        subdev_info->name, index);
1310                        return ret;
1311                }
1312        }
1313
1314        if (sd) {
1315                input = chan_cfg->inputs[index].input_route;
1316                output = chan_cfg->inputs[index].output_route;
1317                ret = v4l2_subdev_call(sd, video, s_routing,
1318                                input, output, 0);
1319                if (ret < 0 && ret != -ENOIOCTLCMD) {
1320                        vpif_dbg(1, debug, "Failed to set input\n");
1321                        return ret;
1322                }
1323        }
1324        ch->input_idx = index;
1325        ch->sd = sd;
1326        /* copy interface parameters to vpif */
1327        ch->vpifparams.iface = chan_cfg->vpif_if;
1328
1329        /* update tvnorms from the sub device input info */
1330        ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
1331        return 0;
1332}
1333
1334/**
1335 * vpif_querystd() - querystd handler
1336 * @file: file ptr
1337 * @priv: file handle
1338 * @std_id: ptr to std id
1339 *
1340 * This function is called to detect standard at the selected input
1341 */
1342static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
1343{
1344        struct vpif_fh *fh = priv;
1345        struct channel_obj *ch = fh->channel;
1346        int ret = 0;
1347
1348        vpif_dbg(2, debug, "vpif_querystd\n");
1349
1350        /* Call querystd function of decoder device */
1351        ret = v4l2_subdev_call(ch->sd, video, querystd, std_id);
1352
1353        if (ret == -ENOIOCTLCMD || ret == -ENODEV)
1354                return -ENODATA;
1355        if (ret) {
1356                vpif_dbg(1, debug, "Failed to query standard for sub devices\n");
1357                return ret;
1358        }
1359
1360        return 0;
1361}
1362
1363/**
1364 * vpif_g_std() - get STD handler
1365 * @file: file ptr
1366 * @priv: file handle
1367 * @std_id: ptr to std id
1368 */
1369static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
1370{
1371        struct vpif_fh *fh = priv;
1372        struct channel_obj *ch = fh->channel;
1373
1374        vpif_dbg(2, debug, "vpif_g_std\n");
1375
1376        *std = ch->video.stdid;
1377        return 0;
1378}
1379
1380/**
1381 * vpif_s_std() - set STD handler
1382 * @file: file ptr
1383 * @priv: file handle
1384 * @std_id: ptr to std id
1385 */
1386static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
1387{
1388        struct vpif_fh *fh = priv;
1389        struct channel_obj *ch = fh->channel;
1390        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1391        int ret = 0;
1392
1393        vpif_dbg(2, debug, "vpif_s_std\n");
1394
1395        if (common->started) {
1396                vpif_err("streaming in progress\n");
1397                return -EBUSY;
1398        }
1399
1400        if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1401            (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1402                if (!fh->initialized) {
1403                        vpif_dbg(1, debug, "Channel Busy\n");
1404                        return -EBUSY;
1405                }
1406        }
1407
1408        ret = v4l2_prio_check(&ch->prio, fh->prio);
1409        if (0 != ret)
1410                return ret;
1411
1412        fh->initialized = 1;
1413
1414        /* Call encoder subdevice function to set the standard */
1415        ch->video.stdid = std_id;
1416        memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
1417
1418        /* Get the information about the standard */
1419        if (vpif_update_std_info(ch)) {
1420                vpif_err("Error getting the standard info\n");
1421                return -EINVAL;
1422        }
1423
1424        /* Configure the default format information */
1425        vpif_config_format(ch);
1426
1427        /* set standard in the sub device */
1428        ret = v4l2_subdev_call(ch->sd, core, s_std, std_id);
1429        if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
1430                vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1431                return ret;
1432        }
1433        return 0;
1434}
1435
1436/**
1437 * vpif_enum_input() - ENUMINPUT handler
1438 * @file: file ptr
1439 * @priv: file handle
1440 * @input: ptr to input structure
1441 */
1442static int vpif_enum_input(struct file *file, void *priv,
1443                                struct v4l2_input *input)
1444{
1445
1446        struct vpif_capture_config *config = vpif_dev->platform_data;
1447        struct vpif_capture_chan_config *chan_cfg;
1448        struct vpif_fh *fh = priv;
1449        struct channel_obj *ch = fh->channel;
1450
1451        chan_cfg = &config->chan_config[ch->channel_id];
1452
1453        if (input->index >= chan_cfg->input_count) {
1454                vpif_dbg(1, debug, "Invalid input index\n");
1455                return -EINVAL;
1456        }
1457
1458        memcpy(input, &chan_cfg->inputs[input->index].input,
1459                sizeof(*input));
1460        return 0;
1461}
1462
1463/**
1464 * vpif_g_input() - Get INPUT handler
1465 * @file: file ptr
1466 * @priv: file handle
1467 * @index: ptr to input index
1468 */
1469static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
1470{
1471        struct vpif_fh *fh = priv;
1472        struct channel_obj *ch = fh->channel;
1473
1474        *index = ch->input_idx;
1475        return 0;
1476}
1477
1478/**
1479 * vpif_s_input() - Set INPUT handler
1480 * @file: file ptr
1481 * @priv: file handle
1482 * @index: input index
1483 */
1484static int vpif_s_input(struct file *file, void *priv, unsigned int index)
1485{
1486        struct vpif_capture_config *config = vpif_dev->platform_data;
1487        struct vpif_capture_chan_config *chan_cfg;
1488        struct vpif_fh *fh = priv;
1489        struct channel_obj *ch = fh->channel;
1490        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1491        int ret;
1492
1493        chan_cfg = &config->chan_config[ch->channel_id];
1494
1495        if (index >= chan_cfg->input_count)
1496                return -EINVAL;
1497
1498        if (common->started) {
1499                vpif_err("Streaming in progress\n");
1500                return -EBUSY;
1501        }
1502
1503        if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1504            (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1505                if (!fh->initialized) {
1506                        vpif_dbg(1, debug, "Channel Busy\n");
1507                        return -EBUSY;
1508                }
1509        }
1510
1511        ret = v4l2_prio_check(&ch->prio, fh->prio);
1512        if (0 != ret)
1513                return ret;
1514
1515        fh->initialized = 1;
1516        return vpif_set_input(config, ch, index);
1517}
1518
1519/**
1520 * vpif_enum_fmt_vid_cap() - ENUM_FMT handler
1521 * @file: file ptr
1522 * @priv: file handle
1523 * @index: input index
1524 */
1525static int vpif_enum_fmt_vid_cap(struct file *file, void  *priv,
1526                                        struct v4l2_fmtdesc *fmt)
1527{
1528        struct vpif_fh *fh = priv;
1529        struct channel_obj *ch = fh->channel;
1530
1531        if (fmt->index != 0) {
1532                vpif_dbg(1, debug, "Invalid format index\n");
1533                return -EINVAL;
1534        }
1535
1536        /* Fill in the information about format */
1537        if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) {
1538                fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1539                strcpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb");
1540                fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
1541        } else {
1542                fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1543                strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
1544                fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
1545        }
1546        return 0;
1547}
1548
1549/**
1550 * vpif_try_fmt_vid_cap() - TRY_FMT handler
1551 * @file: file ptr
1552 * @priv: file handle
1553 * @fmt: ptr to v4l2 format structure
1554 */
1555static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
1556                                struct v4l2_format *fmt)
1557{
1558        struct vpif_fh *fh = priv;
1559        struct channel_obj *ch = fh->channel;
1560        struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
1561
1562        return vpif_check_format(ch, pixfmt, 1);
1563}
1564
1565
1566/**
1567 * vpif_g_fmt_vid_cap() - Set INPUT handler
1568 * @file: file ptr
1569 * @priv: file handle
1570 * @fmt: ptr to v4l2 format structure
1571 */
1572static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
1573                                struct v4l2_format *fmt)
1574{
1575        struct vpif_fh *fh = priv;
1576        struct channel_obj *ch = fh->channel;
1577        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1578
1579        /* Check the validity of the buffer type */
1580        if (common->fmt.type != fmt->type)
1581                return -EINVAL;
1582
1583        /* Fill in the information about format */
1584        *fmt = common->fmt;
1585        return 0;
1586}
1587
1588/**
1589 * vpif_s_fmt_vid_cap() - Set FMT handler
1590 * @file: file ptr
1591 * @priv: file handle
1592 * @fmt: ptr to v4l2 format structure
1593 */
1594static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
1595                                struct v4l2_format *fmt)
1596{
1597        struct vpif_fh *fh = priv;
1598        struct channel_obj *ch = fh->channel;
1599        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1600        struct v4l2_pix_format *pixfmt;
1601        int ret = 0;
1602
1603        vpif_dbg(2, debug, "%s\n", __func__);
1604
1605        /* If streaming is started, return error */
1606        if (common->started) {
1607                vpif_dbg(1, debug, "Streaming is started\n");
1608                return -EBUSY;
1609        }
1610
1611        if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1612            (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1613                if (!fh->initialized) {
1614                        vpif_dbg(1, debug, "Channel Busy\n");
1615                        return -EBUSY;
1616                }
1617        }
1618
1619        ret = v4l2_prio_check(&ch->prio, fh->prio);
1620        if (0 != ret)
1621                return ret;
1622
1623        fh->initialized = 1;
1624
1625        pixfmt = &fmt->fmt.pix;
1626        /* Check for valid field format */
1627        ret = vpif_check_format(ch, pixfmt, 0);
1628
1629        if (ret)
1630                return ret;
1631        /* store the format in the channel object */
1632        common->fmt = *fmt;
1633        return 0;
1634}
1635
1636/**
1637 * vpif_querycap() - QUERYCAP handler
1638 * @file: file ptr
1639 * @priv: file handle
1640 * @cap: ptr to v4l2_capability structure
1641 */
1642static int vpif_querycap(struct file *file, void  *priv,
1643                                struct v4l2_capability *cap)
1644{
1645        struct vpif_capture_config *config = vpif_dev->platform_data;
1646
1647        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1648        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1649        snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpif_dev));
1650        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1651                 dev_name(vpif_dev));
1652        strlcpy(cap->card, config->card_name, sizeof(cap->card));
1653
1654        return 0;
1655}
1656
1657/**
1658 * vpif_g_priority() - get priority handler
1659 * @file: file ptr
1660 * @priv: file handle
1661 * @prio: ptr to v4l2_priority structure
1662 */
1663static int vpif_g_priority(struct file *file, void *priv,
1664                           enum v4l2_priority *prio)
1665{
1666        struct vpif_fh *fh = priv;
1667        struct channel_obj *ch = fh->channel;
1668
1669        *prio = v4l2_prio_max(&ch->prio);
1670
1671        return 0;
1672}
1673
1674/**
1675 * vpif_s_priority() - set priority handler
1676 * @file: file ptr
1677 * @priv: file handle
1678 * @prio: ptr to v4l2_priority structure
1679 */
1680static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
1681{
1682        struct vpif_fh *fh = priv;
1683        struct channel_obj *ch = fh->channel;
1684
1685        return v4l2_prio_change(&ch->prio, &fh->prio, p);
1686}
1687
1688/**
1689 * vpif_cropcap() - cropcap handler
1690 * @file: file ptr
1691 * @priv: file handle
1692 * @crop: ptr to v4l2_cropcap structure
1693 */
1694static int vpif_cropcap(struct file *file, void *priv,
1695                        struct v4l2_cropcap *crop)
1696{
1697        struct vpif_fh *fh = priv;
1698        struct channel_obj *ch = fh->channel;
1699        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1700
1701        if (V4L2_BUF_TYPE_VIDEO_CAPTURE != crop->type)
1702                return -EINVAL;
1703
1704        crop->bounds.left = 0;
1705        crop->bounds.top = 0;
1706        crop->bounds.height = common->height;
1707        crop->bounds.width = common->width;
1708        crop->defrect = crop->bounds;
1709        return 0;
1710}
1711
1712/**
1713 * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
1714 * @file: file ptr
1715 * @priv: file handle
1716 * @timings: input timings
1717 */
1718static int
1719vpif_enum_dv_timings(struct file *file, void *priv,
1720                     struct v4l2_enum_dv_timings *timings)
1721{
1722        struct vpif_fh *fh = priv;
1723        struct channel_obj *ch = fh->channel;
1724        int ret;
1725
1726        ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
1727        if (ret == -ENOIOCTLCMD || ret == -ENODEV)
1728                return -EINVAL;
1729        return ret;
1730}
1731
1732/**
1733 * vpif_query_dv_timings() - QUERY_DV_TIMINGS handler
1734 * @file: file ptr
1735 * @priv: file handle
1736 * @timings: input timings
1737 */
1738static int
1739vpif_query_dv_timings(struct file *file, void *priv,
1740                      struct v4l2_dv_timings *timings)
1741{
1742        struct vpif_fh *fh = priv;
1743        struct channel_obj *ch = fh->channel;
1744        int ret;
1745
1746        ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings);
1747        if (ret == -ENOIOCTLCMD || ret == -ENODEV)
1748                return -ENODATA;
1749        return ret;
1750}
1751
1752/**
1753 * vpif_s_dv_timings() - S_DV_TIMINGS handler
1754 * @file: file ptr
1755 * @priv: file handle
1756 * @timings: digital video timings
1757 */
1758static int vpif_s_dv_timings(struct file *file, void *priv,
1759                struct v4l2_dv_timings *timings)
1760{
1761        struct vpif_fh *fh = priv;
1762        struct channel_obj *ch = fh->channel;
1763        struct vpif_params *vpifparams = &ch->vpifparams;
1764        struct vpif_channel_config_params *std_info = &vpifparams->std_info;
1765        struct video_obj *vid_ch = &ch->video;
1766        struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
1767        int ret;
1768
1769        if (timings->type != V4L2_DV_BT_656_1120) {
1770                vpif_dbg(2, debug, "Timing type not defined\n");
1771                return -EINVAL;
1772        }
1773
1774        /* Configure subdevice timings, if any */
1775        ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
1776        if (ret == -ENOIOCTLCMD || ret == -ENODEV)
1777                ret = 0;
1778        if (ret < 0) {
1779                vpif_dbg(2, debug, "Error setting custom DV timings\n");
1780                return ret;
1781        }
1782
1783        if (!(timings->bt.width && timings->bt.height &&
1784                                (timings->bt.hbackporch ||
1785                                 timings->bt.hfrontporch ||
1786                                 timings->bt.hsync) &&
1787                                timings->bt.vfrontporch &&
1788                                (timings->bt.vbackporch ||
1789                                 timings->bt.vsync))) {
1790                vpif_dbg(2, debug, "Timings for width, height, "
1791                                "horizontal back porch, horizontal sync, "
1792                                "horizontal front porch, vertical back porch, "
1793                                "vertical sync and vertical back porch "
1794                                "must be defined\n");
1795                return -EINVAL;
1796        }
1797
1798        vid_ch->dv_timings = *timings;
1799
1800        /* Configure video port timings */
1801
1802        std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
1803                bt->hsync - 8;
1804        std_info->sav2eav = bt->width;
1805
1806        std_info->l1 = 1;
1807        std_info->l3 = bt->vsync + bt->vbackporch + 1;
1808
1809        if (bt->interlaced) {
1810                if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
1811                        std_info->vsize = bt->height * 2 +
1812                                bt->vfrontporch + bt->vsync + bt->vbackporch +
1813                                bt->il_vfrontporch + bt->il_vsync +
1814                                bt->il_vbackporch;
1815                        std_info->l5 = std_info->vsize/2 -
1816                                (bt->vfrontporch - 1);
1817                        std_info->l7 = std_info->vsize/2 + 1;
1818                        std_info->l9 = std_info->l7 + bt->il_vsync +
1819                                bt->il_vbackporch + 1;
1820                        std_info->l11 = std_info->vsize -
1821                                (bt->il_vfrontporch - 1);
1822                } else {
1823                        vpif_dbg(2, debug, "Required timing values for "
1824                                        "interlaced BT format missing\n");
1825                        return -EINVAL;
1826                }
1827        } else {
1828                std_info->vsize = bt->height + bt->vfrontporch +
1829                        bt->vsync + bt->vbackporch;
1830                std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
1831        }
1832        strncpy(std_info->name, "Custom timings BT656/1120", VPIF_MAX_NAME);
1833        std_info->width = bt->width;
1834        std_info->height = bt->height;
1835        std_info->frm_fmt = bt->interlaced ? 0 : 1;
1836        std_info->ycmux_mode = 0;
1837        std_info->capture_format = 0;
1838        std_info->vbi_supported = 0;
1839        std_info->hd_sd = 1;
1840        std_info->stdid = 0;
1841
1842        vid_ch->stdid = 0;
1843        return 0;
1844}
1845
1846/**
1847 * vpif_g_dv_timings() - G_DV_TIMINGS handler
1848 * @file: file ptr
1849 * @priv: file handle
1850 * @timings: digital video timings
1851 */
1852static int vpif_g_dv_timings(struct file *file, void *priv,
1853                struct v4l2_dv_timings *timings)
1854{
1855        struct vpif_fh *fh = priv;
1856        struct channel_obj *ch = fh->channel;
1857        struct video_obj *vid_ch = &ch->video;
1858
1859        *timings = vid_ch->dv_timings;
1860
1861        return 0;
1862}
1863
1864/*
1865 * vpif_log_status() - Status information
1866 * @file: file ptr
1867 * @priv: file handle
1868 *
1869 * Returns zero.
1870 */
1871static int vpif_log_status(struct file *filep, void *priv)
1872{
1873        /* status for sub devices */
1874        v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
1875
1876        return 0;
1877}
1878
1879/* vpif capture ioctl operations */
1880static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
1881        .vidioc_querycap                = vpif_querycap,
1882        .vidioc_g_priority              = vpif_g_priority,
1883        .vidioc_s_priority              = vpif_s_priority,
1884        .vidioc_enum_fmt_vid_cap        = vpif_enum_fmt_vid_cap,
1885        .vidioc_g_fmt_vid_cap           = vpif_g_fmt_vid_cap,
1886        .vidioc_s_fmt_vid_cap           = vpif_s_fmt_vid_cap,
1887        .vidioc_try_fmt_vid_cap         = vpif_try_fmt_vid_cap,
1888        .vidioc_enum_input              = vpif_enum_input,
1889        .vidioc_s_input                 = vpif_s_input,
1890        .vidioc_g_input                 = vpif_g_input,
1891        .vidioc_reqbufs                 = vpif_reqbufs,
1892        .vidioc_querybuf                = vpif_querybuf,
1893        .vidioc_querystd                = vpif_querystd,
1894        .vidioc_s_std                   = vpif_s_std,
1895        .vidioc_g_std                   = vpif_g_std,
1896        .vidioc_qbuf                    = vpif_qbuf,
1897        .vidioc_dqbuf                   = vpif_dqbuf,
1898        .vidioc_streamon                = vpif_streamon,
1899        .vidioc_streamoff               = vpif_streamoff,
1900        .vidioc_cropcap                 = vpif_cropcap,
1901        .vidioc_enum_dv_timings         = vpif_enum_dv_timings,
1902        .vidioc_query_dv_timings        = vpif_query_dv_timings,
1903        .vidioc_s_dv_timings            = vpif_s_dv_timings,
1904        .vidioc_g_dv_timings            = vpif_g_dv_timings,
1905        .vidioc_log_status              = vpif_log_status,
1906};
1907
1908/* vpif file operations */
1909static struct v4l2_file_operations vpif_fops = {
1910        .owner = THIS_MODULE,
1911        .open = vpif_open,
1912        .release = vpif_release,
1913        .unlocked_ioctl = video_ioctl2,
1914        .mmap = vpif_mmap,
1915        .poll = vpif_poll
1916};
1917
1918/* vpif video template */
1919static struct video_device vpif_video_template = {
1920        .name           = "vpif",
1921        .fops           = &vpif_fops,
1922        .minor          = -1,
1923        .ioctl_ops      = &vpif_ioctl_ops,
1924};
1925
1926/**
1927 * initialize_vpif() - Initialize vpif data structures
1928 *
1929 * Allocate memory for data structures and initialize them
1930 */
1931static int initialize_vpif(void)
1932{
1933        int err = 0, i, j;
1934        int free_channel_objects_index;
1935
1936        /* Default number of buffers should be 3 */
1937        if ((ch0_numbuffers > 0) &&
1938            (ch0_numbuffers < config_params.min_numbuffers))
1939                ch0_numbuffers = config_params.min_numbuffers;
1940        if ((ch1_numbuffers > 0) &&
1941            (ch1_numbuffers < config_params.min_numbuffers))
1942                ch1_numbuffers = config_params.min_numbuffers;
1943
1944        /* Set buffer size to min buffers size if it is invalid */
1945        if (ch0_bufsize < config_params.min_bufsize[VPIF_CHANNEL0_VIDEO])
1946                ch0_bufsize =
1947                    config_params.min_bufsize[VPIF_CHANNEL0_VIDEO];
1948        if (ch1_bufsize < config_params.min_bufsize[VPIF_CHANNEL1_VIDEO])
1949                ch1_bufsize =
1950                    config_params.min_bufsize[VPIF_CHANNEL1_VIDEO];
1951
1952        config_params.numbuffers[VPIF_CHANNEL0_VIDEO] = ch0_numbuffers;
1953        config_params.numbuffers[VPIF_CHANNEL1_VIDEO] = ch1_numbuffers;
1954        if (ch0_numbuffers) {
1955                config_params.channel_bufsize[VPIF_CHANNEL0_VIDEO]
1956                    = ch0_bufsize;
1957        }
1958        if (ch1_numbuffers) {
1959                config_params.channel_bufsize[VPIF_CHANNEL1_VIDEO]
1960                    = ch1_bufsize;
1961        }
1962
1963        /* Allocate memory for six channel objects */
1964        for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
1965                vpif_obj.dev[i] =
1966                    kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL);
1967                /* If memory allocation fails, return error */
1968                if (!vpif_obj.dev[i]) {
1969                        free_channel_objects_index = i;
1970                        err = -ENOMEM;
1971                        goto vpif_init_free_channel_objects;
1972                }
1973        }
1974        return 0;
1975
1976vpif_init_free_channel_objects:
1977        for (j = 0; j < free_channel_objects_index; j++)
1978                kfree(vpif_obj.dev[j]);
1979        return err;
1980}
1981
1982/**
1983 * vpif_probe : This function probes the vpif capture driver
1984 * @pdev: platform device pointer
1985 *
1986 * This creates device entries by register itself to the V4L2 driver and
1987 * initializes fields of each channel objects
1988 */
1989static __init int vpif_probe(struct platform_device *pdev)
1990{
1991        struct vpif_subdev_info *subdevdata;
1992        struct vpif_capture_config *config;
1993        int i, j, k, err;
1994        int res_idx = 0;
1995        struct i2c_adapter *i2c_adap;
1996        struct channel_obj *ch;
1997        struct common_obj *common;
1998        struct video_device *vfd;
1999        struct resource *res;
2000        int subdev_count;
2001        size_t size;
2002
2003        vpif_dev = &pdev->dev;
2004
2005        err = initialize_vpif();
2006        if (err) {
2007                v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
2008                return err;
2009        }
2010
2011        err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
2012        if (err) {
2013                v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
2014                return err;
2015        }
2016
2017        while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
2018                err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
2019                                        IRQF_SHARED, "VPIF_Capture",
2020                                        (void *)(&vpif_obj.dev[res_idx]->
2021                                        channel_id));
2022                if (err) {
2023                        err = -EINVAL;
2024                        goto vpif_unregister;
2025                }
2026                res_idx++;
2027        }
2028
2029        for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2030                /* Get the pointer to the channel object */
2031                ch = vpif_obj.dev[i];
2032                /* Allocate memory for video device */
2033                vfd = video_device_alloc();
2034                if (NULL == vfd) {
2035                        for (j = 0; j < i; j++) {
2036                                ch = vpif_obj.dev[j];
2037                                video_device_release(ch->video_dev);
2038                        }
2039                        err = -ENOMEM;
2040                        goto vpif_unregister;
2041                }
2042
2043                /* Initialize field of video device */
2044                *vfd = vpif_video_template;
2045                vfd->v4l2_dev = &vpif_obj.v4l2_dev;
2046                vfd->release = video_device_release;
2047                snprintf(vfd->name, sizeof(vfd->name),
2048                         "VPIF_Capture_DRIVER_V%s",
2049                         VPIF_CAPTURE_VERSION);
2050                /* Set video_dev to the video device */
2051                ch->video_dev = vfd;
2052        }
2053
2054        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2055        if (res) {
2056                size = resource_size(res);
2057                /* The resources are divided into two equal memory and when we
2058                 * have HD output we can add them together
2059                 */
2060                for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
2061                        ch = vpif_obj.dev[j];
2062                        ch->channel_id = j;
2063                        /* only enabled if second resource exists */
2064                        config_params.video_limit[ch->channel_id] = 0;
2065                        if (size)
2066                                config_params.video_limit[ch->channel_id] =
2067                                                                        size/2;
2068                }
2069        }
2070
2071        i2c_adap = i2c_get_adapter(1);
2072        config = pdev->dev.platform_data;
2073
2074        subdev_count = config->subdev_count;
2075        vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count,
2076                                GFP_KERNEL);
2077        if (vpif_obj.sd == NULL) {
2078                vpif_err("unable to allocate memory for subdevice pointers\n");
2079                err = -ENOMEM;
2080                goto vpif_sd_error;
2081        }
2082
2083        for (i = 0; i < subdev_count; i++) {
2084                subdevdata = &config->subdev_info[i];
2085                vpif_obj.sd[i] =
2086                        v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
2087                                                  i2c_adap,
2088                                                  &subdevdata->board_info,
2089                                                  NULL);
2090
2091                if (!vpif_obj.sd[i]) {
2092                        vpif_err("Error registering v4l2 subdevice\n");
2093                        err = -ENODEV;
2094                        goto probe_subdev_out;
2095                }
2096                v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
2097                          subdevdata->name);
2098        }
2099
2100        for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
2101                ch = vpif_obj.dev[j];
2102                ch->channel_id = j;
2103                common = &(ch->common[VPIF_VIDEO_INDEX]);
2104                spin_lock_init(&common->irqlock);
2105                mutex_init(&common->lock);
2106                ch->video_dev->lock = &common->lock;
2107                /* Initialize prio member of channel object */
2108                v4l2_prio_init(&ch->prio);
2109                video_set_drvdata(ch->video_dev, ch);
2110
2111                /* select input 0 */
2112                err = vpif_set_input(config, ch, 0);
2113                if (err)
2114                        goto probe_out;
2115
2116                err = video_register_device(ch->video_dev,
2117                                            VFL_TYPE_GRABBER, (j ? 1 : 0));
2118                if (err)
2119                        goto probe_out;
2120        }
2121        v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n");
2122        return 0;
2123
2124probe_out:
2125        for (k = 0; k < j; k++) {
2126                /* Get the pointer to the channel object */
2127                ch = vpif_obj.dev[k];
2128                /* Unregister video device */
2129                video_unregister_device(ch->video_dev);
2130        }
2131probe_subdev_out:
2132        /* free sub devices memory */
2133        kfree(vpif_obj.sd);
2134
2135vpif_sd_error:
2136        for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2137                ch = vpif_obj.dev[i];
2138                /* Note: does nothing if ch->video_dev == NULL */
2139                video_device_release(ch->video_dev);
2140        }
2141vpif_unregister:
2142        v4l2_device_unregister(&vpif_obj.v4l2_dev);
2143
2144        return err;
2145}
2146
2147/**
2148 * vpif_remove() - driver remove handler
2149 * @device: ptr to platform device structure
2150 *
2151 * The vidoe device is unregistered
2152 */
2153static int vpif_remove(struct platform_device *device)
2154{
2155        struct channel_obj *ch;
2156        int i;
2157
2158        v4l2_device_unregister(&vpif_obj.v4l2_dev);
2159
2160        kfree(vpif_obj.sd);
2161        /* un-register device */
2162        for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2163                /* Get the pointer to the channel object */
2164                ch = vpif_obj.dev[i];
2165                /* Unregister video device */
2166                video_unregister_device(ch->video_dev);
2167                kfree(vpif_obj.dev[i]);
2168        }
2169        return 0;
2170}
2171
2172#ifdef CONFIG_PM
2173/**
2174 * vpif_suspend: vpif device suspend
2175 */
2176static int vpif_suspend(struct device *dev)
2177{
2178
2179        struct common_obj *common;
2180        struct channel_obj *ch;
2181        int i;
2182
2183        for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2184                /* Get the pointer to the channel object */
2185                ch = vpif_obj.dev[i];
2186                common = &ch->common[VPIF_VIDEO_INDEX];
2187                mutex_lock(&common->lock);
2188                if (ch->usrs && common->io_usrs) {
2189                        /* Disable channel */
2190                        if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
2191                                enable_channel0(0);
2192                                channel0_intr_enable(0);
2193                        }
2194                        if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
2195                            common->started == 2) {
2196                                enable_channel1(0);
2197                                channel1_intr_enable(0);
2198                        }
2199                }
2200                mutex_unlock(&common->lock);
2201        }
2202
2203        return 0;
2204}
2205
2206/*
2207 * vpif_resume: vpif device suspend
2208 */
2209static int vpif_resume(struct device *dev)
2210{
2211        struct common_obj *common;
2212        struct channel_obj *ch;
2213        int i;
2214
2215        for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2216                /* Get the pointer to the channel object */
2217                ch = vpif_obj.dev[i];
2218                common = &ch->common[VPIF_VIDEO_INDEX];
2219                mutex_lock(&common->lock);
2220                if (ch->usrs && common->io_usrs) {
2221                        /* Disable channel */
2222                        if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
2223                                enable_channel0(1);
2224                                channel0_intr_enable(1);
2225                        }
2226                        if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
2227                            common->started == 2) {
2228                                enable_channel1(1);
2229                                channel1_intr_enable(1);
2230                        }
2231                }
2232                mutex_unlock(&common->lock);
2233        }
2234
2235        return 0;
2236}
2237
2238static const struct dev_pm_ops vpif_dev_pm_ops = {
2239        .suspend = vpif_suspend,
2240        .resume = vpif_resume,
2241};
2242
2243#define vpif_pm_ops (&vpif_dev_pm_ops)
2244#else
2245#define vpif_pm_ops NULL
2246#endif
2247
2248static __refdata struct platform_driver vpif_driver = {
2249        .driver = {
2250                .name   = "vpif_capture",
2251                .owner  = THIS_MODULE,
2252                .pm     = vpif_pm_ops,
2253        },
2254        .probe = vpif_probe,
2255        .remove = vpif_remove,
2256};
2257
2258module_platform_driver(vpif_driver);
2259