1822 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2009 Texas Instruments Inc4 * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com>5 *6 * TODO : add support for VBI & HBI data service7 * add static buffer allocation8 */9 10#include <linux/module.h>11#include <linux/interrupt.h>12#include <linux/of_graph.h>13#include <linux/platform_device.h>14#include <linux/slab.h>15 16#include <media/v4l2-fwnode.h>17#include <media/v4l2-ioctl.h>18#include <media/i2c/tvp514x.h>19#include <media/v4l2-mediabus.h>20 21#include <linux/videodev2.h>22 23#include "vpif.h"24#include "vpif_capture.h"25 26MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");27MODULE_LICENSE("GPL");28MODULE_VERSION(VPIF_CAPTURE_VERSION);29 30#define vpif_err(fmt, arg...) v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)31#define vpif_dbg(level, debug, fmt, arg...) \32 v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)33 34static int debug = 1;35 36module_param(debug, int, 0644);37 38MODULE_PARM_DESC(debug, "Debug level 0-1");39 40#define VPIF_DRIVER_NAME "vpif_capture"41MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);42 43/* global variables */44static struct vpif_device vpif_obj = { {NULL} };45static struct device *vpif_dev;46static void vpif_calculate_offsets(struct channel_obj *ch);47static void vpif_config_addr(struct channel_obj *ch, int muxmode);48 49static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] = { {1, 1} };50 51/* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */52static int ycmux_mode;53 54static inline55struct vpif_cap_buffer *to_vpif_buffer(struct vb2_v4l2_buffer *vb)56{57 return container_of(vb, struct vpif_cap_buffer, vb);58}59 60/**61 * vpif_buffer_prepare : callback function for buffer prepare62 * @vb: ptr to vb2_buffer63 *64 * This is the callback function for buffer prepare when vb2_qbuf()65 * function is called. The buffer is prepared and user space virtual address66 * or user address is converted into physical address67 */68static int vpif_buffer_prepare(struct vb2_buffer *vb)69{70 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);71 struct vb2_queue *q = vb->vb2_queue;72 struct channel_obj *ch = vb2_get_drv_priv(q);73 struct common_obj *common;74 unsigned long addr;75 76 vpif_dbg(2, debug, "vpif_buffer_prepare\n");77 78 common = &ch->common[VPIF_VIDEO_INDEX];79 80 vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);81 if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))82 return -EINVAL;83 84 vbuf->field = common->fmt.fmt.pix.field;85 86 addr = vb2_dma_contig_plane_dma_addr(vb, 0);87 if (!IS_ALIGNED((addr + common->ytop_off), 8) ||88 !IS_ALIGNED((addr + common->ybtm_off), 8) ||89 !IS_ALIGNED((addr + common->ctop_off), 8) ||90 !IS_ALIGNED((addr + common->cbtm_off), 8)) {91 vpif_dbg(1, debug, "offset is not aligned\n");92 return -EINVAL;93 }94 95 return 0;96}97 98/**99 * vpif_buffer_queue_setup : Callback function for buffer setup.100 * @vq: vb2_queue ptr101 * @nbuffers: ptr to number of buffers requested by application102 * @nplanes: contains number of distinct video planes needed to hold a frame103 * @sizes: contains the size (in bytes) of each plane.104 * @alloc_devs: ptr to allocation context105 *106 * This callback function is called when reqbuf() is called to adjust107 * the buffer count and buffer size108 */109static int vpif_buffer_queue_setup(struct vb2_queue *vq,110 unsigned int *nbuffers, unsigned int *nplanes,111 unsigned int sizes[], struct device *alloc_devs[])112{113 struct channel_obj *ch = vb2_get_drv_priv(vq);114 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];115 unsigned size = common->fmt.fmt.pix.sizeimage;116 unsigned int q_num_bufs = vb2_get_num_buffers(vq);117 118 vpif_dbg(2, debug, "vpif_buffer_setup\n");119 120 if (*nplanes) {121 if (sizes[0] < size)122 return -EINVAL;123 size = sizes[0];124 }125 126 if (q_num_bufs + *nbuffers < 3)127 *nbuffers = 3 - q_num_bufs;128 129 *nplanes = 1;130 sizes[0] = size;131 132 /* Calculate the offset for Y and C data in the buffer */133 vpif_calculate_offsets(ch);134 135 return 0;136}137 138/**139 * vpif_buffer_queue : Callback function to add buffer to DMA queue140 * @vb: ptr to vb2_buffer141 */142static void vpif_buffer_queue(struct vb2_buffer *vb)143{144 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);145 struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);146 struct vpif_cap_buffer *buf = to_vpif_buffer(vbuf);147 struct common_obj *common;148 unsigned long flags;149 150 common = &ch->common[VPIF_VIDEO_INDEX];151 152 vpif_dbg(2, debug, "vpif_buffer_queue\n");153 154 spin_lock_irqsave(&common->irqlock, flags);155 /* add the buffer to the DMA queue */156 list_add_tail(&buf->list, &common->dma_queue);157 spin_unlock_irqrestore(&common->irqlock, flags);158}159 160/**161 * vpif_start_streaming : Starts the DMA engine for streaming162 * @vq: ptr to vb2_buffer163 * @count: number of buffers164 */165static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)166{167 struct vpif_capture_config *vpif_config_data =168 vpif_dev->platform_data;169 struct channel_obj *ch = vb2_get_drv_priv(vq);170 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];171 struct vpif_params *vpif = &ch->vpifparams;172 struct vpif_cap_buffer *buf, *tmp;173 unsigned long addr, flags;174 int ret;175 176 /* Initialize field_id */177 ch->field_id = 0;178 179 /* configure 1 or 2 channel mode */180 if (vpif_config_data->setup_input_channel_mode) {181 ret = vpif_config_data->182 setup_input_channel_mode(vpif->std_info.ycmux_mode);183 if (ret < 0) {184 vpif_dbg(1, debug, "can't set vpif channel mode\n");185 goto err;186 }187 }188 189 ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);190 if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {191 vpif_dbg(1, debug, "stream on failed in subdev\n");192 goto err;193 }194 195 /* Call vpif_set_params function to set the parameters and addresses */196 ret = vpif_set_video_params(vpif, ch->channel_id);197 if (ret < 0) {198 vpif_dbg(1, debug, "can't set video params\n");199 goto err;200 }201 202 ycmux_mode = ret;203 vpif_config_addr(ch, ret);204 205 /* Get the next frame from the buffer queue */206 spin_lock_irqsave(&common->irqlock, flags);207 common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,208 struct vpif_cap_buffer, list);209 /* Remove buffer from the buffer queue */210 list_del(&common->cur_frm->list);211 spin_unlock_irqrestore(&common->irqlock, flags);212 213 addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb.vb2_buf, 0);214 215 common->set_addr(addr + common->ytop_off,216 addr + common->ybtm_off,217 addr + common->ctop_off,218 addr + common->cbtm_off);219 220 /**221 * Set interrupt for both the fields in VPIF Register enable channel in222 * VPIF register223 */224 channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;225 if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {226 channel0_intr_assert();227 channel0_intr_enable(1);228 enable_channel0(1);229 }230 if (VPIF_CHANNEL1_VIDEO == ch->channel_id ||231 ycmux_mode == 2) {232 channel1_intr_assert();233 channel1_intr_enable(1);234 enable_channel1(1);235 }236 237 return 0;238 239err:240 spin_lock_irqsave(&common->irqlock, flags);241 list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {242 list_del(&buf->list);243 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);244 }245 spin_unlock_irqrestore(&common->irqlock, flags);246 247 return ret;248}249 250/**251 * vpif_stop_streaming : Stop the DMA engine252 * @vq: ptr to vb2_queue253 *254 * This callback stops the DMA engine and any remaining buffers255 * in the DMA queue are released.256 */257static void vpif_stop_streaming(struct vb2_queue *vq)258{259 struct channel_obj *ch = vb2_get_drv_priv(vq);260 struct common_obj *common;261 unsigned long flags;262 int ret;263 264 common = &ch->common[VPIF_VIDEO_INDEX];265 266 /* Disable channel as per its device type and channel id */267 if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {268 enable_channel0(0);269 channel0_intr_enable(0);270 }271 if (VPIF_CHANNEL1_VIDEO == ch->channel_id ||272 ycmux_mode == 2) {273 enable_channel1(0);274 channel1_intr_enable(0);275 }276 277 ycmux_mode = 0;278 279 ret = v4l2_subdev_call(ch->sd, video, s_stream, 0);280 if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)281 vpif_dbg(1, debug, "stream off failed in subdev\n");282 283 /* release all active buffers */284 if (common->cur_frm == common->next_frm) {285 vb2_buffer_done(&common->cur_frm->vb.vb2_buf,286 VB2_BUF_STATE_ERROR);287 } else {288 if (common->cur_frm)289 vb2_buffer_done(&common->cur_frm->vb.vb2_buf,290 VB2_BUF_STATE_ERROR);291 if (common->next_frm)292 vb2_buffer_done(&common->next_frm->vb.vb2_buf,293 VB2_BUF_STATE_ERROR);294 }295 296 spin_lock_irqsave(&common->irqlock, flags);297 while (!list_empty(&common->dma_queue)) {298 common->next_frm = list_entry(common->dma_queue.next,299 struct vpif_cap_buffer, list);300 list_del(&common->next_frm->list);301 vb2_buffer_done(&common->next_frm->vb.vb2_buf,302 VB2_BUF_STATE_ERROR);303 }304 spin_unlock_irqrestore(&common->irqlock, flags);305}306 307static const struct vb2_ops video_qops = {308 .queue_setup = vpif_buffer_queue_setup,309 .buf_prepare = vpif_buffer_prepare,310 .start_streaming = vpif_start_streaming,311 .stop_streaming = vpif_stop_streaming,312 .buf_queue = vpif_buffer_queue,313 .wait_prepare = vb2_ops_wait_prepare,314 .wait_finish = vb2_ops_wait_finish,315};316 317/**318 * vpif_process_buffer_complete: process a completed buffer319 * @common: ptr to common channel object320 *321 * This function time stamp the buffer and mark it as DONE. It also322 * wake up any process waiting on the QUEUE and set the next buffer323 * as current324 */325static void vpif_process_buffer_complete(struct common_obj *common)326{327 common->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();328 vb2_buffer_done(&common->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);329 /* Make curFrm pointing to nextFrm */330 common->cur_frm = common->next_frm;331}332 333/**334 * vpif_schedule_next_buffer: set next buffer address for capture335 * @common : ptr to common channel object336 *337 * This function will get next buffer from the dma queue and338 * set the buffer address in the vpif register for capture.339 * the buffer is marked active340 */341static void vpif_schedule_next_buffer(struct common_obj *common)342{343 unsigned long addr = 0;344 345 spin_lock(&common->irqlock);346 common->next_frm = list_entry(common->dma_queue.next,347 struct vpif_cap_buffer, list);348 /* Remove that buffer from the buffer queue */349 list_del(&common->next_frm->list);350 spin_unlock(&common->irqlock);351 addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb.vb2_buf, 0);352 353 /* Set top and bottom field addresses in VPIF registers */354 common->set_addr(addr + common->ytop_off,355 addr + common->ybtm_off,356 addr + common->ctop_off,357 addr + common->cbtm_off);358}359 360/**361 * vpif_channel_isr : ISR handler for vpif capture362 * @irq: irq number363 * @dev_id: dev_id ptr364 *365 * It changes status of the captured buffer, takes next buffer from the queue366 * and sets its address in VPIF registers367 */368static irqreturn_t vpif_channel_isr(int irq, void *dev_id)369{370 struct vpif_device *dev = &vpif_obj;371 struct common_obj *common;372 struct channel_obj *ch;373 int channel_id;374 int fid = -1, i;375 376 channel_id = *(int *)(dev_id);377 if (!vpif_intr_status(channel_id))378 return IRQ_NONE;379 380 ch = dev->dev[channel_id];381 382 for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {383 common = &ch->common[i];384 /* skip If streaming is not started in this channel */385 /* Check the field format */386 if (1 == ch->vpifparams.std_info.frm_fmt ||387 common->fmt.fmt.pix.field == V4L2_FIELD_NONE) {388 /* Progressive mode */389 spin_lock(&common->irqlock);390 if (list_empty(&common->dma_queue)) {391 spin_unlock(&common->irqlock);392 continue;393 }394 spin_unlock(&common->irqlock);395 396 if (!channel_first_int[i][channel_id])397 vpif_process_buffer_complete(common);398 399 channel_first_int[i][channel_id] = 0;400 401 vpif_schedule_next_buffer(common);402 403 404 channel_first_int[i][channel_id] = 0;405 } else {406 /**407 * Interlaced mode. If it is first interrupt, ignore408 * it409 */410 if (channel_first_int[i][channel_id]) {411 channel_first_int[i][channel_id] = 0;412 continue;413 }414 if (0 == i) {415 ch->field_id ^= 1;416 /* Get field id from VPIF registers */417 fid = vpif_channel_getfid(ch->channel_id);418 if (fid != ch->field_id) {419 /**420 * If field id does not match stored421 * field id, make them in sync422 */423 if (0 == fid)424 ch->field_id = fid;425 return IRQ_HANDLED;426 }427 }428 /* device field id and local field id are in sync */429 if (0 == fid) {430 /* this is even field */431 if (common->cur_frm == common->next_frm)432 continue;433 434 /* mark the current buffer as done */435 vpif_process_buffer_complete(common);436 } else if (1 == fid) {437 /* odd field */438 spin_lock(&common->irqlock);439 if (list_empty(&common->dma_queue) ||440 (common->cur_frm != common->next_frm)) {441 spin_unlock(&common->irqlock);442 continue;443 }444 spin_unlock(&common->irqlock);445 446 vpif_schedule_next_buffer(common);447 }448 }449 }450 return IRQ_HANDLED;451}452 453/**454 * vpif_update_std_info() - update standard related info455 * @ch: ptr to channel object456 *457 * For a given standard selected by application, update values458 * in the device data structures459 */460static int vpif_update_std_info(struct channel_obj *ch)461{462 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];463 struct vpif_params *vpifparams = &ch->vpifparams;464 const struct vpif_channel_config_params *config;465 struct vpif_channel_config_params *std_info = &vpifparams->std_info;466 struct video_obj *vid_ch = &ch->video;467 int index;468 struct v4l2_pix_format *pixfmt = &common->fmt.fmt.pix;469 470 vpif_dbg(2, debug, "vpif_update_std_info\n");471 472 /*473 * if called after try_fmt or g_fmt, there will already be a size474 * so use that by default.475 */476 if (pixfmt->width && pixfmt->height) {477 if (pixfmt->field == V4L2_FIELD_ANY ||478 pixfmt->field == V4L2_FIELD_NONE)479 pixfmt->field = V4L2_FIELD_NONE;480 481 vpifparams->iface.if_type = VPIF_IF_BT656;482 if (pixfmt->pixelformat == V4L2_PIX_FMT_SGRBG10 ||483 pixfmt->pixelformat == V4L2_PIX_FMT_SBGGR8)484 vpifparams->iface.if_type = VPIF_IF_RAW_BAYER;485 486 if (pixfmt->pixelformat == V4L2_PIX_FMT_SGRBG10)487 vpifparams->params.data_sz = 1; /* 10 bits/pixel. */488 489 /*490 * For raw formats from camera sensors, we don't need491 * the std_info from table lookup, so nothing else to do here.492 */493 if (vpifparams->iface.if_type == VPIF_IF_RAW_BAYER) {494 memset(std_info, 0, sizeof(struct vpif_channel_config_params));495 vpifparams->std_info.capture_format = 1; /* CCD/raw mode */496 return 0;497 }498 }499 500 for (index = 0; index < vpif_ch_params_count; index++) {501 config = &vpif_ch_params[index];502 if (config->hd_sd == 0) {503 vpif_dbg(2, debug, "SD format\n");504 if (config->stdid & vid_ch->stdid) {505 memcpy(std_info, config, sizeof(*config));506 break;507 }508 } else {509 vpif_dbg(2, debug, "HD format\n");510 if (!memcmp(&config->dv_timings, &vid_ch->dv_timings,511 sizeof(vid_ch->dv_timings))) {512 memcpy(std_info, config, sizeof(*config));513 break;514 }515 }516 }517 518 /* standard not found */519 if (index == vpif_ch_params_count)520 return -EINVAL;521 522 common->fmt.fmt.pix.width = std_info->width;523 common->width = std_info->width;524 common->fmt.fmt.pix.height = std_info->height;525 common->height = std_info->height;526 common->fmt.fmt.pix.sizeimage = common->height * common->width * 2;527 common->fmt.fmt.pix.bytesperline = std_info->width;528 vpifparams->video_params.hpitch = std_info->width;529 vpifparams->video_params.storage_mode = std_info->frm_fmt;530 531 if (vid_ch->stdid)532 common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;533 else534 common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;535 536 if (ch->vpifparams.std_info.frm_fmt)537 common->fmt.fmt.pix.field = V4L2_FIELD_NONE;538 else539 common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;540 541 if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)542 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;543 else544 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV16;545 546 common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;547 548 return 0;549}550 551/**552 * vpif_calculate_offsets : This function calculates buffers offsets553 * @ch : ptr to channel object554 *555 * This function calculates buffer offsets for Y and C in the top and556 * bottom field557 */558static void vpif_calculate_offsets(struct channel_obj *ch)559{560 unsigned int hpitch, sizeimage;561 struct video_obj *vid_ch = &(ch->video);562 struct vpif_params *vpifparams = &ch->vpifparams;563 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];564 enum v4l2_field field = common->fmt.fmt.pix.field;565 566 vpif_dbg(2, debug, "vpif_calculate_offsets\n");567 568 if (V4L2_FIELD_ANY == field) {569 if (vpifparams->std_info.frm_fmt)570 vid_ch->buf_field = V4L2_FIELD_NONE;571 else572 vid_ch->buf_field = V4L2_FIELD_INTERLACED;573 } else574 vid_ch->buf_field = common->fmt.fmt.pix.field;575 576 sizeimage = common->fmt.fmt.pix.sizeimage;577 578 hpitch = common->fmt.fmt.pix.bytesperline;579 580 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||581 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {582 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */583 common->ytop_off = 0;584 common->ybtm_off = hpitch;585 common->ctop_off = sizeimage / 2;586 common->cbtm_off = sizeimage / 2 + hpitch;587 } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {588 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */589 common->ytop_off = 0;590 common->ybtm_off = sizeimage / 4;591 common->ctop_off = sizeimage / 2;592 common->cbtm_off = common->ctop_off + sizeimage / 4;593 } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {594 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */595 common->ybtm_off = 0;596 common->ytop_off = sizeimage / 4;597 common->cbtm_off = sizeimage / 2;598 common->ctop_off = common->cbtm_off + sizeimage / 4;599 }600 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||601 (V4L2_FIELD_INTERLACED == vid_ch->buf_field))602 vpifparams->video_params.storage_mode = 1;603 else604 vpifparams->video_params.storage_mode = 0;605 606 if (1 == vpifparams->std_info.frm_fmt)607 vpifparams->video_params.hpitch =608 common->fmt.fmt.pix.bytesperline;609 else {610 if ((field == V4L2_FIELD_ANY)611 || (field == V4L2_FIELD_INTERLACED))612 vpifparams->video_params.hpitch =613 common->fmt.fmt.pix.bytesperline * 2;614 else615 vpifparams->video_params.hpitch =616 common->fmt.fmt.pix.bytesperline;617 }618 619 ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;620}621 622/**623 * vpif_config_addr() - function to configure buffer address in vpif624 * @ch: channel ptr625 * @muxmode: channel mux mode626 */627static void vpif_config_addr(struct channel_obj *ch, int muxmode)628{629 struct common_obj *common;630 631 vpif_dbg(2, debug, "vpif_config_addr\n");632 633 common = &(ch->common[VPIF_VIDEO_INDEX]);634 635 if (VPIF_CHANNEL1_VIDEO == ch->channel_id)636 common->set_addr = ch1_set_video_buf_addr;637 else if (2 == muxmode)638 common->set_addr = ch0_set_video_buf_addr_yc_nmux;639 else640 common->set_addr = ch0_set_video_buf_addr;641}642 643/**644 * vpif_input_to_subdev() - Maps input to sub device645 * @vpif_cfg: global config ptr646 * @chan_cfg: channel config ptr647 * @input_index: Given input index from application648 *649 * lookup the sub device information for a given input index.650 * we report all the inputs to application. inputs table also651 * has sub device name for the each input652 */653static int vpif_input_to_subdev(654 struct vpif_capture_config *vpif_cfg,655 struct vpif_capture_chan_config *chan_cfg,656 int input_index)657{658 struct vpif_subdev_info *subdev_info;659 const char *subdev_name;660 int i;661 662 vpif_dbg(2, debug, "vpif_input_to_subdev\n");663 664 if (!chan_cfg)665 return -1;666 if (input_index >= chan_cfg->input_count)667 return -1;668 subdev_name = chan_cfg->inputs[input_index].subdev_name;669 if (!subdev_name)670 return -1;671 672 /* loop through the sub device list to get the sub device info */673 for (i = 0; i < vpif_cfg->subdev_count; i++) {674 subdev_info = &vpif_cfg->subdev_info[i];675 if (subdev_info && !strcmp(subdev_info->name, subdev_name))676 return i;677 }678 return -1;679}680 681/**682 * vpif_set_input() - Select an input683 * @vpif_cfg: global config ptr684 * @ch: channel685 * @index: Given input index from application686 *687 * Select the given input.688 */689static int vpif_set_input(690 struct vpif_capture_config *vpif_cfg,691 struct channel_obj *ch,692 int index)693{694 struct vpif_capture_chan_config *chan_cfg =695 &vpif_cfg->chan_config[ch->channel_id];696 struct vpif_subdev_info *subdev_info = NULL;697 struct v4l2_subdev *sd = NULL;698 u32 input = 0, output = 0;699 int sd_index;700 int ret;701 702 sd_index = vpif_input_to_subdev(vpif_cfg, chan_cfg, index);703 if (sd_index >= 0) {704 sd = vpif_obj.sd[sd_index];705 subdev_info = &vpif_cfg->subdev_info[sd_index];706 } else {707 /* no subdevice, no input to setup */708 return 0;709 }710 711 /* first setup input path from sub device to vpif */712 if (sd && vpif_cfg->setup_input_path) {713 ret = vpif_cfg->setup_input_path(ch->channel_id,714 subdev_info->name);715 if (ret < 0) {716 vpif_dbg(1, debug, "couldn't setup input path for the" \717 " sub device %s, for input index %d\n",718 subdev_info->name, index);719 return ret;720 }721 }722 723 if (sd) {724 input = chan_cfg->inputs[index].input_route;725 output = chan_cfg->inputs[index].output_route;726 ret = v4l2_subdev_call(sd, video, s_routing,727 input, output, 0);728 if (ret < 0 && ret != -ENOIOCTLCMD) {729 vpif_dbg(1, debug, "Failed to set input\n");730 return ret;731 }732 }733 ch->input_idx = index;734 ch->sd = sd;735 /* copy interface parameters to vpif */736 ch->vpifparams.iface = chan_cfg->vpif_if;737 738 /* update tvnorms from the sub device input info */739 ch->video_dev.tvnorms = chan_cfg->inputs[index].input.std;740 return 0;741}742 743/**744 * vpif_querystd() - querystd handler745 * @file: file ptr746 * @priv: file handle747 * @std_id: ptr to std id748 *749 * This function is called to detect standard at the selected input750 */751static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)752{753 struct video_device *vdev = video_devdata(file);754 struct channel_obj *ch = video_get_drvdata(vdev);755 int ret;756 757 vpif_dbg(2, debug, "vpif_querystd\n");758 759 /* Call querystd function of decoder device */760 ret = v4l2_subdev_call(ch->sd, video, querystd, std_id);761 762 if (ret == -ENOIOCTLCMD || ret == -ENODEV)763 return -ENODATA;764 if (ret) {765 vpif_dbg(1, debug, "Failed to query standard for sub devices\n");766 return ret;767 }768 769 return 0;770}771 772/**773 * vpif_g_std() - get STD handler774 * @file: file ptr775 * @priv: file handle776 * @std: ptr to std id777 */778static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)779{780 struct vpif_capture_config *config = vpif_dev->platform_data;781 struct video_device *vdev = video_devdata(file);782 struct channel_obj *ch = video_get_drvdata(vdev);783 struct vpif_capture_chan_config *chan_cfg;784 struct v4l2_input input;785 786 vpif_dbg(2, debug, "vpif_g_std\n");787 788 if (!config->chan_config[ch->channel_id].inputs)789 return -ENODATA;790 791 chan_cfg = &config->chan_config[ch->channel_id];792 input = chan_cfg->inputs[ch->input_idx].input;793 if (input.capabilities != V4L2_IN_CAP_STD)794 return -ENODATA;795 796 *std = ch->video.stdid;797 return 0;798}799 800/**801 * vpif_s_std() - set STD handler802 * @file: file ptr803 * @priv: file handle804 * @std_id: ptr to std id805 */806static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)807{808 struct vpif_capture_config *config = vpif_dev->platform_data;809 struct video_device *vdev = video_devdata(file);810 struct channel_obj *ch = video_get_drvdata(vdev);811 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];812 struct vpif_capture_chan_config *chan_cfg;813 struct v4l2_input input;814 int ret;815 816 vpif_dbg(2, debug, "vpif_s_std\n");817 818 if (!config->chan_config[ch->channel_id].inputs)819 return -ENODATA;820 821 chan_cfg = &config->chan_config[ch->channel_id];822 input = chan_cfg->inputs[ch->input_idx].input;823 if (input.capabilities != V4L2_IN_CAP_STD)824 return -ENODATA;825 826 if (vb2_is_busy(&common->buffer_queue))827 return -EBUSY;828 829 /* Call encoder subdevice function to set the standard */830 ch->video.stdid = std_id;831 memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));832 833 /* Get the information about the standard */834 if (vpif_update_std_info(ch)) {835 vpif_err("Error getting the standard info\n");836 return -EINVAL;837 }838 839 /* set standard in the sub device */840 ret = v4l2_subdev_call(ch->sd, video, s_std, std_id);841 if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {842 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");843 return ret;844 }845 return 0;846}847 848/**849 * vpif_enum_input() - ENUMINPUT handler850 * @file: file ptr851 * @priv: file handle852 * @input: ptr to input structure853 */854static int vpif_enum_input(struct file *file, void *priv,855 struct v4l2_input *input)856{857 858 struct vpif_capture_config *config = vpif_dev->platform_data;859 struct video_device *vdev = video_devdata(file);860 struct channel_obj *ch = video_get_drvdata(vdev);861 struct vpif_capture_chan_config *chan_cfg;862 863 chan_cfg = &config->chan_config[ch->channel_id];864 865 if (input->index >= chan_cfg->input_count)866 return -EINVAL;867 868 memcpy(input, &chan_cfg->inputs[input->index].input,869 sizeof(*input));870 return 0;871}872 873/**874 * vpif_g_input() - Get INPUT handler875 * @file: file ptr876 * @priv: file handle877 * @index: ptr to input index878 */879static int vpif_g_input(struct file *file, void *priv, unsigned int *index)880{881 struct video_device *vdev = video_devdata(file);882 struct channel_obj *ch = video_get_drvdata(vdev);883 884 *index = ch->input_idx;885 return 0;886}887 888/**889 * vpif_s_input() - Set INPUT handler890 * @file: file ptr891 * @priv: file handle892 * @index: input index893 */894static int vpif_s_input(struct file *file, void *priv, unsigned int index)895{896 struct vpif_capture_config *config = vpif_dev->platform_data;897 struct video_device *vdev = video_devdata(file);898 struct channel_obj *ch = video_get_drvdata(vdev);899 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];900 struct vpif_capture_chan_config *chan_cfg;901 902 chan_cfg = &config->chan_config[ch->channel_id];903 904 if (index >= chan_cfg->input_count)905 return -EINVAL;906 907 if (vb2_is_busy(&common->buffer_queue))908 return -EBUSY;909 910 return vpif_set_input(config, ch, index);911}912 913/**914 * vpif_enum_fmt_vid_cap() - ENUM_FMT handler915 * @file: file ptr916 * @priv: file handle917 * @fmt: ptr to V4L2 format descriptor918 */919static int vpif_enum_fmt_vid_cap(struct file *file, void *priv,920 struct v4l2_fmtdesc *fmt)921{922 struct video_device *vdev = video_devdata(file);923 struct channel_obj *ch = video_get_drvdata(vdev);924 925 if (fmt->index != 0) {926 vpif_dbg(1, debug, "Invalid format index\n");927 return -EINVAL;928 }929 930 /* Fill in the information about format */931 if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)932 fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;933 else934 fmt->pixelformat = V4L2_PIX_FMT_NV16;935 return 0;936}937 938/**939 * vpif_try_fmt_vid_cap() - TRY_FMT handler940 * @file: file ptr941 * @priv: file handle942 * @fmt: ptr to v4l2 format structure943 */944static int vpif_try_fmt_vid_cap(struct file *file, void *priv,945 struct v4l2_format *fmt)946{947 struct video_device *vdev = video_devdata(file);948 struct channel_obj *ch = video_get_drvdata(vdev);949 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;950 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);951 952 common->fmt = *fmt;953 vpif_update_std_info(ch);954 955 pixfmt->field = common->fmt.fmt.pix.field;956 pixfmt->colorspace = common->fmt.fmt.pix.colorspace;957 pixfmt->bytesperline = common->fmt.fmt.pix.width;958 pixfmt->width = common->fmt.fmt.pix.width;959 pixfmt->height = common->fmt.fmt.pix.height;960 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;961 if (pixfmt->pixelformat == V4L2_PIX_FMT_SGRBG10) {962 pixfmt->bytesperline = common->fmt.fmt.pix.width * 2;963 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;964 }965 966 dev_dbg(vpif_dev, "%s: %d x %d; pitch=%d pixelformat=0x%08x, field=%d, size=%d\n", __func__,967 pixfmt->width, pixfmt->height,968 pixfmt->bytesperline, pixfmt->pixelformat,969 pixfmt->field, pixfmt->sizeimage);970 971 return 0;972}973 974 975/**976 * vpif_g_fmt_vid_cap() - Set INPUT handler977 * @file: file ptr978 * @priv: file handle979 * @fmt: ptr to v4l2 format structure980 */981static int vpif_g_fmt_vid_cap(struct file *file, void *priv,982 struct v4l2_format *fmt)983{984 struct video_device *vdev = video_devdata(file);985 struct channel_obj *ch = video_get_drvdata(vdev);986 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];987 struct v4l2_pix_format *pix_fmt = &fmt->fmt.pix;988 struct v4l2_subdev_format format = {989 .which = V4L2_SUBDEV_FORMAT_ACTIVE,990 };991 struct v4l2_mbus_framefmt *mbus_fmt = &format.format;992 int ret;993 994 /* Check the validity of the buffer type */995 if (common->fmt.type != fmt->type)996 return -EINVAL;997 998 /* By default, use currently set fmt */999 *fmt = common->fmt;1000 1001 /* If subdev has get_fmt, use that to override */1002 ret = v4l2_subdev_call(ch->sd, pad, get_fmt, NULL, &format);1003 if (!ret && mbus_fmt->code) {1004 v4l2_fill_pix_format(pix_fmt, mbus_fmt);1005 pix_fmt->bytesperline = pix_fmt->width;1006 if (mbus_fmt->code == MEDIA_BUS_FMT_SGRBG10_1X10) {1007 /* e.g. mt9v032 */1008 pix_fmt->pixelformat = V4L2_PIX_FMT_SGRBG10;1009 pix_fmt->bytesperline = pix_fmt->width * 2;1010 } else if (mbus_fmt->code == MEDIA_BUS_FMT_UYVY8_2X8) {1011 /* e.g. tvp514x */1012 pix_fmt->pixelformat = V4L2_PIX_FMT_NV16;1013 pix_fmt->bytesperline = pix_fmt->width * 2;1014 } else {1015 dev_warn(vpif_dev, "%s: Unhandled media-bus format 0x%x\n",1016 __func__, mbus_fmt->code);1017 }1018 pix_fmt->sizeimage = pix_fmt->bytesperline * pix_fmt->height;1019 dev_dbg(vpif_dev, "%s: %d x %d; pitch=%d, pixelformat=0x%08x, code=0x%x, field=%d, size=%d\n", __func__,1020 pix_fmt->width, pix_fmt->height,1021 pix_fmt->bytesperline, pix_fmt->pixelformat,1022 mbus_fmt->code, pix_fmt->field, pix_fmt->sizeimage);1023 1024 common->fmt = *fmt;1025 vpif_update_std_info(ch);1026 }1027 1028 return 0;1029}1030 1031/**1032 * vpif_s_fmt_vid_cap() - Set FMT handler1033 * @file: file ptr1034 * @priv: file handle1035 * @fmt: ptr to v4l2 format structure1036 */1037static int vpif_s_fmt_vid_cap(struct file *file, void *priv,1038 struct v4l2_format *fmt)1039{1040 struct video_device *vdev = video_devdata(file);1041 struct channel_obj *ch = video_get_drvdata(vdev);1042 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];1043 int ret;1044 1045 vpif_dbg(2, debug, "%s\n", __func__);1046 1047 if (vb2_is_busy(&common->buffer_queue))1048 return -EBUSY;1049 1050 ret = vpif_try_fmt_vid_cap(file, priv, fmt);1051 if (ret)1052 return ret;1053 1054 /* store the format in the channel object */1055 common->fmt = *fmt;1056 return 0;1057}1058 1059/**1060 * vpif_querycap() - QUERYCAP handler1061 * @file: file ptr1062 * @priv: file handle1063 * @cap: ptr to v4l2_capability structure1064 */1065static int vpif_querycap(struct file *file, void *priv,1066 struct v4l2_capability *cap)1067{1068 struct vpif_capture_config *config = vpif_dev->platform_data;1069 1070 strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));1071 strscpy(cap->card, config->card_name, sizeof(cap->card));1072 1073 return 0;1074}1075 1076/**1077 * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler1078 * @file: file ptr1079 * @priv: file handle1080 * @timings: input timings1081 */1082static int1083vpif_enum_dv_timings(struct file *file, void *priv,1084 struct v4l2_enum_dv_timings *timings)1085{1086 struct vpif_capture_config *config = vpif_dev->platform_data;1087 struct video_device *vdev = video_devdata(file);1088 struct channel_obj *ch = video_get_drvdata(vdev);1089 struct vpif_capture_chan_config *chan_cfg;1090 struct v4l2_input input;1091 int ret;1092 1093 if (!config->chan_config[ch->channel_id].inputs)1094 return -ENODATA;1095 1096 chan_cfg = &config->chan_config[ch->channel_id];1097 input = chan_cfg->inputs[ch->input_idx].input;1098 if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)1099 return -ENODATA;1100 1101 timings->pad = 0;1102 1103 ret = v4l2_subdev_call(ch->sd, pad, enum_dv_timings, timings);1104 if (ret == -ENOIOCTLCMD || ret == -ENODEV)1105 return -EINVAL;1106 1107 return ret;1108}1109 1110/**1111 * vpif_query_dv_timings() - QUERY_DV_TIMINGS handler1112 * @file: file ptr1113 * @priv: file handle1114 * @timings: input timings1115 */1116static int1117vpif_query_dv_timings(struct file *file, void *priv,1118 struct v4l2_dv_timings *timings)1119{1120 struct vpif_capture_config *config = vpif_dev->platform_data;1121 struct video_device *vdev = video_devdata(file);1122 struct channel_obj *ch = video_get_drvdata(vdev);1123 struct vpif_capture_chan_config *chan_cfg;1124 struct v4l2_input input;1125 int ret;1126 1127 if (!config->chan_config[ch->channel_id].inputs)1128 return -ENODATA;1129 1130 chan_cfg = &config->chan_config[ch->channel_id];1131 input = chan_cfg->inputs[ch->input_idx].input;1132 if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)1133 return -ENODATA;1134 1135 ret = v4l2_subdev_call(ch->sd, pad, query_dv_timings, 0, timings);1136 if (ret == -ENOIOCTLCMD || ret == -ENODEV)1137 return -ENODATA;1138 1139 return ret;1140}1141 1142/**1143 * vpif_s_dv_timings() - S_DV_TIMINGS handler1144 * @file: file ptr1145 * @priv: file handle1146 * @timings: digital video timings1147 */1148static int vpif_s_dv_timings(struct file *file, void *priv,1149 struct v4l2_dv_timings *timings)1150{1151 struct vpif_capture_config *config = vpif_dev->platform_data;1152 struct video_device *vdev = video_devdata(file);1153 struct channel_obj *ch = video_get_drvdata(vdev);1154 struct vpif_params *vpifparams = &ch->vpifparams;1155 struct vpif_channel_config_params *std_info = &vpifparams->std_info;1156 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];1157 struct video_obj *vid_ch = &ch->video;1158 struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;1159 struct vpif_capture_chan_config *chan_cfg;1160 struct v4l2_input input;1161 int ret;1162 1163 if (!config->chan_config[ch->channel_id].inputs)1164 return -ENODATA;1165 1166 chan_cfg = &config->chan_config[ch->channel_id];1167 input = chan_cfg->inputs[ch->input_idx].input;1168 if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)1169 return -ENODATA;1170 1171 if (timings->type != V4L2_DV_BT_656_1120) {1172 vpif_dbg(2, debug, "Timing type not defined\n");1173 return -EINVAL;1174 }1175 1176 if (vb2_is_busy(&common->buffer_queue))1177 return -EBUSY;1178 1179 /* Configure subdevice timings, if any */1180 ret = v4l2_subdev_call(ch->sd, pad, s_dv_timings, 0, timings);1181 if (ret == -ENOIOCTLCMD || ret == -ENODEV)1182 ret = 0;1183 if (ret < 0) {1184 vpif_dbg(2, debug, "Error setting custom DV timings\n");1185 return ret;1186 }1187 1188 if (!(timings->bt.width && timings->bt.height &&1189 (timings->bt.hbackporch ||1190 timings->bt.hfrontporch ||1191 timings->bt.hsync) &&1192 timings->bt.vfrontporch &&1193 (timings->bt.vbackporch ||1194 timings->bt.vsync))) {1195 vpif_dbg(2, debug, "Timings for width, height, horizontal back porch, horizontal sync, horizontal front porch, vertical back porch, vertical sync and vertical back porch must be defined\n");1196 return -EINVAL;1197 }1198 1199 vid_ch->dv_timings = *timings;1200 1201 /* Configure video port timings */1202 1203 std_info->eav2sav = V4L2_DV_BT_BLANKING_WIDTH(bt) - 8;1204 std_info->sav2eav = bt->width;1205 1206 std_info->l1 = 1;1207 std_info->l3 = bt->vsync + bt->vbackporch + 1;1208 1209 std_info->vsize = V4L2_DV_BT_FRAME_HEIGHT(bt);1210 if (bt->interlaced) {1211 if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {1212 std_info->l5 = std_info->vsize/2 -1213 (bt->vfrontporch - 1);1214 std_info->l7 = std_info->vsize/2 + 1;1215 std_info->l9 = std_info->l7 + bt->il_vsync +1216 bt->il_vbackporch + 1;1217 std_info->l11 = std_info->vsize -1218 (bt->il_vfrontporch - 1);1219 } else {1220 vpif_dbg(2, debug, "Required timing values for interlaced BT format missing\n");1221 return -EINVAL;1222 }1223 } else {1224 std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);1225 }1226 strscpy(std_info->name, "Custom timings BT656/1120",1227 sizeof(std_info->name));1228 std_info->width = bt->width;1229 std_info->height = bt->height;1230 std_info->frm_fmt = bt->interlaced ? 0 : 1;1231 std_info->ycmux_mode = 0;1232 std_info->capture_format = 0;1233 std_info->vbi_supported = 0;1234 std_info->hd_sd = 1;1235 std_info->stdid = 0;1236 1237 vid_ch->stdid = 0;1238 return 0;1239}1240 1241/**1242 * vpif_g_dv_timings() - G_DV_TIMINGS handler1243 * @file: file ptr1244 * @priv: file handle1245 * @timings: digital video timings1246 */1247static int vpif_g_dv_timings(struct file *file, void *priv,1248 struct v4l2_dv_timings *timings)1249{1250 struct vpif_capture_config *config = vpif_dev->platform_data;1251 struct video_device *vdev = video_devdata(file);1252 struct channel_obj *ch = video_get_drvdata(vdev);1253 struct video_obj *vid_ch = &ch->video;1254 struct vpif_capture_chan_config *chan_cfg;1255 struct v4l2_input input;1256 1257 if (!config->chan_config[ch->channel_id].inputs)1258 return -ENODATA;1259 1260 chan_cfg = &config->chan_config[ch->channel_id];1261 input = chan_cfg->inputs[ch->input_idx].input;1262 if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)1263 return -ENODATA;1264 1265 *timings = vid_ch->dv_timings;1266 1267 return 0;1268}1269 1270/*1271 * vpif_log_status() - Status information1272 * @file: file ptr1273 * @priv: file handle1274 *1275 * Returns zero.1276 */1277static int vpif_log_status(struct file *filep, void *priv)1278{1279 /* status for sub devices */1280 v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);1281 1282 return 0;1283}1284 1285/* vpif capture ioctl operations */1286static const struct v4l2_ioctl_ops vpif_ioctl_ops = {1287 .vidioc_querycap = vpif_querycap,1288 .vidioc_enum_fmt_vid_cap = vpif_enum_fmt_vid_cap,1289 .vidioc_g_fmt_vid_cap = vpif_g_fmt_vid_cap,1290 .vidioc_s_fmt_vid_cap = vpif_s_fmt_vid_cap,1291 .vidioc_try_fmt_vid_cap = vpif_try_fmt_vid_cap,1292 1293 .vidioc_enum_input = vpif_enum_input,1294 .vidioc_s_input = vpif_s_input,1295 .vidioc_g_input = vpif_g_input,1296 1297 .vidioc_reqbufs = vb2_ioctl_reqbufs,1298 .vidioc_create_bufs = vb2_ioctl_create_bufs,1299 .vidioc_querybuf = vb2_ioctl_querybuf,1300 .vidioc_qbuf = vb2_ioctl_qbuf,1301 .vidioc_dqbuf = vb2_ioctl_dqbuf,1302 .vidioc_expbuf = vb2_ioctl_expbuf,1303 .vidioc_streamon = vb2_ioctl_streamon,1304 .vidioc_streamoff = vb2_ioctl_streamoff,1305 1306 .vidioc_querystd = vpif_querystd,1307 .vidioc_s_std = vpif_s_std,1308 .vidioc_g_std = vpif_g_std,1309 1310 .vidioc_enum_dv_timings = vpif_enum_dv_timings,1311 .vidioc_query_dv_timings = vpif_query_dv_timings,1312 .vidioc_s_dv_timings = vpif_s_dv_timings,1313 .vidioc_g_dv_timings = vpif_g_dv_timings,1314 1315 .vidioc_log_status = vpif_log_status,1316};1317 1318/* vpif file operations */1319static const struct v4l2_file_operations vpif_fops = {1320 .owner = THIS_MODULE,1321 .open = v4l2_fh_open,1322 .release = vb2_fop_release,1323 .unlocked_ioctl = video_ioctl2,1324 .mmap = vb2_fop_mmap,1325 .poll = vb2_fop_poll1326};1327 1328/**1329 * initialize_vpif() - Initialize vpif data structures1330 *1331 * Allocate memory for data structures and initialize them1332 */1333static int initialize_vpif(void)1334{1335 int err, i, j;1336 int free_channel_objects_index;1337 1338 /* Allocate memory for six channel objects */1339 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {1340 vpif_obj.dev[i] =1341 kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL);1342 /* If memory allocation fails, return error */1343 if (!vpif_obj.dev[i]) {1344 free_channel_objects_index = i;1345 err = -ENOMEM;1346 goto vpif_init_free_channel_objects;1347 }1348 }1349 return 0;1350 1351vpif_init_free_channel_objects:1352 for (j = 0; j < free_channel_objects_index; j++)1353 kfree(vpif_obj.dev[j]);1354 return err;1355}1356 1357static inline void free_vpif_objs(void)1358{1359 int i;1360 1361 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)1362 kfree(vpif_obj.dev[i]);1363}1364 1365static int vpif_async_bound(struct v4l2_async_notifier *notifier,1366 struct v4l2_subdev *subdev,1367 struct v4l2_async_connection *asd)1368{1369 int i;1370 1371 for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {1372 struct v4l2_async_connection *_asd = vpif_obj.config->asd[i];1373 const struct fwnode_handle *fwnode = _asd->match.fwnode;1374 1375 if (fwnode == subdev->fwnode) {1376 vpif_obj.sd[i] = subdev;1377 vpif_obj.config->chan_config->inputs[i].subdev_name =1378 (char *)to_of_node(subdev->fwnode)->full_name;1379 vpif_dbg(2, debug,1380 "%s: setting input %d subdev_name = %s\n",1381 __func__, i,1382 vpif_obj.config->chan_config->inputs[i].subdev_name);1383 return 0;1384 }1385 }1386 1387 for (i = 0; i < vpif_obj.config->subdev_count; i++)1388 if (!strcmp(vpif_obj.config->subdev_info[i].name,1389 subdev->name)) {1390 vpif_obj.sd[i] = subdev;1391 return 0;1392 }1393 1394 return -EINVAL;1395}1396 1397static int vpif_probe_complete(void)1398{1399 struct common_obj *common;1400 struct video_device *vdev;1401 struct channel_obj *ch;1402 struct vb2_queue *q;1403 int j, err, k;1404 1405 for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {1406 ch = vpif_obj.dev[j];1407 ch->channel_id = j;1408 common = &(ch->common[VPIF_VIDEO_INDEX]);1409 spin_lock_init(&common->irqlock);1410 mutex_init(&common->lock);1411 1412 /* select input 0 */1413 err = vpif_set_input(vpif_obj.config, ch, 0);1414 if (err)1415 goto probe_out;1416 1417 /* set initial format */1418 ch->video.stdid = V4L2_STD_525_60;1419 memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));1420 common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;1421 vpif_update_std_info(ch);1422 1423 /* Initialize vb2 queue */1424 q = &common->buffer_queue;1425 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;1426 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;1427 q->drv_priv = ch;1428 q->ops = &video_qops;1429 q->mem_ops = &vb2_dma_contig_memops;1430 q->buf_struct_size = sizeof(struct vpif_cap_buffer);1431 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;1432 q->min_queued_buffers = 1;1433 q->lock = &common->lock;1434 q->dev = vpif_dev;1435 1436 err = vb2_queue_init(q);1437 if (err) {1438 vpif_err("vpif_capture: vb2_queue_init() failed\n");1439 goto probe_out;1440 }1441 1442 INIT_LIST_HEAD(&common->dma_queue);1443 1444 /* Initialize the video_device structure */1445 vdev = &ch->video_dev;1446 strscpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));1447 vdev->release = video_device_release_empty;1448 vdev->fops = &vpif_fops;1449 vdev->ioctl_ops = &vpif_ioctl_ops;1450 vdev->v4l2_dev = &vpif_obj.v4l2_dev;1451 vdev->vfl_dir = VFL_DIR_RX;1452 vdev->queue = q;1453 vdev->lock = &common->lock;1454 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;1455 video_set_drvdata(&ch->video_dev, ch);1456 err = video_register_device(vdev,1457 VFL_TYPE_VIDEO, (j ? 1 : 0));1458 if (err)1459 goto probe_out;1460 }1461 1462 v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n");1463 return 0;1464 1465probe_out:1466 for (k = 0; k < j; k++) {1467 /* Get the pointer to the channel object */1468 ch = vpif_obj.dev[k];1469 /* Unregister video device */1470 video_unregister_device(&ch->video_dev);1471 }1472 1473 return err;1474}1475 1476static int vpif_async_complete(struct v4l2_async_notifier *notifier)1477{1478 return vpif_probe_complete();1479}1480 1481static const struct v4l2_async_notifier_operations vpif_async_ops = {1482 .bound = vpif_async_bound,1483 .complete = vpif_async_complete,1484};1485 1486static struct vpif_capture_config *1487vpif_capture_get_pdata(struct platform_device *pdev,1488 struct v4l2_device *v4l2_dev)1489{1490 struct device_node *endpoint;1491 struct device_node *rem = NULL;1492 struct vpif_capture_config *pdata;1493 struct vpif_subdev_info *sdinfo;1494 struct vpif_capture_chan_config *chan;1495 unsigned int i;1496 1497 v4l2_async_nf_init(&vpif_obj.notifier, v4l2_dev);1498 1499 /*1500 * DT boot: OF node from parent device contains1501 * video ports & endpoints data.1502 */1503 if (pdev->dev.parent && pdev->dev.parent->of_node)1504 pdev->dev.of_node = pdev->dev.parent->of_node;1505 if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)1506 return pdev->dev.platform_data;1507 1508 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);1509 if (!pdata)1510 return NULL;1511 pdata->subdev_info =1512 devm_kcalloc(&pdev->dev,1513 VPIF_CAPTURE_NUM_CHANNELS,1514 sizeof(*pdata->subdev_info),1515 GFP_KERNEL);1516 1517 if (!pdata->subdev_info)1518 return NULL;1519 1520 i = 0;1521 for_each_endpoint_of_node(pdev->dev.of_node, endpoint) {1522 struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };1523 unsigned int flags;1524 int err;1525 1526 rem = of_graph_get_remote_port_parent(endpoint);1527 if (!rem) {1528 dev_dbg(&pdev->dev, "Remote device at %pOF not found\n",1529 endpoint);1530 goto done;1531 }1532 1533 sdinfo = &pdata->subdev_info[i];1534 chan = &pdata->chan_config[i];1535 chan->inputs = devm_kcalloc(&pdev->dev,1536 VPIF_CAPTURE_NUM_CHANNELS,1537 sizeof(*chan->inputs),1538 GFP_KERNEL);1539 if (!chan->inputs)1540 goto err_cleanup;1541 1542 chan->input_count++;1543 chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;1544 chan->inputs[i].input.std = V4L2_STD_ALL;1545 chan->inputs[i].input.capabilities = V4L2_IN_CAP_STD;1546 1547 err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),1548 &bus_cfg);1549 if (err) {1550 dev_err(&pdev->dev, "Could not parse the endpoint\n");1551 of_node_put(rem);1552 goto done;1553 }1554 1555 dev_dbg(&pdev->dev, "Endpoint %pOF, bus_width = %d\n",1556 endpoint, bus_cfg.bus.parallel.bus_width);1557 1558 flags = bus_cfg.bus.parallel.flags;1559 1560 if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)1561 chan->vpif_if.hd_pol = 1;1562 1563 if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)1564 chan->vpif_if.vd_pol = 1;1565 1566 dev_dbg(&pdev->dev, "Remote device %pOF found\n", rem);1567 sdinfo->name = rem->full_name;1568 1569 pdata->asd[i] = v4l2_async_nf_add_fwnode(&vpif_obj.notifier,1570 of_fwnode_handle(rem),1571 struct v4l2_async_connection);1572 if (IS_ERR(pdata->asd[i]))1573 goto err_cleanup;1574 1575 of_node_put(rem);1576 1577 i++;1578 if (i >= VPIF_CAPTURE_NUM_CHANNELS)1579 break;1580 }1581 1582done:1583 of_node_put(endpoint);1584 pdata->asd_sizes[0] = i;1585 pdata->subdev_count = i;1586 pdata->card_name = "DA850/OMAP-L138 Video Capture";1587 1588 return pdata;1589 1590err_cleanup:1591 of_node_put(rem);1592 of_node_put(endpoint);1593 v4l2_async_nf_cleanup(&vpif_obj.notifier);1594 1595 return NULL;1596}1597 1598/**1599 * vpif_probe : This function probes the vpif capture driver1600 * @pdev: platform device pointer1601 *1602 * This creates device entries by register itself to the V4L2 driver and1603 * initializes fields of each channel objects1604 */1605static __init int vpif_probe(struct platform_device *pdev)1606{1607 struct vpif_subdev_info *subdevdata;1608 struct i2c_adapter *i2c_adap;1609 int subdev_count;1610 int res_idx = 0;1611 int i, err;1612 1613 vpif_dev = &pdev->dev;1614 1615 err = initialize_vpif();1616 if (err) {1617 v4l2_err(vpif_dev->driver, "Error initializing vpif\n");1618 return err;1619 }1620 1621 err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);1622 if (err) {1623 v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");1624 goto vpif_free;1625 }1626 1627 do {1628 int irq;1629 1630 err = platform_get_irq_optional(pdev, res_idx);1631 if (err < 0 && err != -ENXIO)1632 goto vpif_unregister;1633 if (err > 0)1634 irq = err;1635 else1636 break;1637 1638 err = devm_request_irq(&pdev->dev, irq, vpif_channel_isr,1639 IRQF_SHARED, VPIF_DRIVER_NAME,1640 (void *)(&vpif_obj.dev[res_idx]->channel_id));1641 if (err)1642 goto vpif_unregister;1643 } while (++res_idx);1644 1645 pdev->dev.platform_data =1646 vpif_capture_get_pdata(pdev, &vpif_obj.v4l2_dev);1647 if (!pdev->dev.platform_data) {1648 err = -EINVAL;1649 dev_warn(&pdev->dev, "Missing platform data. Giving up.\n");1650 goto vpif_unregister;1651 }1652 1653 vpif_obj.config = pdev->dev.platform_data;1654 1655 subdev_count = vpif_obj.config->subdev_count;1656 vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL);1657 if (!vpif_obj.sd) {1658 err = -ENOMEM;1659 goto probe_subdev_out;1660 }1661 1662 if (!vpif_obj.config->asd_sizes[0]) {1663 int i2c_id = vpif_obj.config->i2c_adapter_id;1664 1665 i2c_adap = i2c_get_adapter(i2c_id);1666 WARN_ON(!i2c_adap);1667 for (i = 0; i < subdev_count; i++) {1668 subdevdata = &vpif_obj.config->subdev_info[i];1669 vpif_obj.sd[i] =1670 v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,1671 i2c_adap,1672 &subdevdata->1673 board_info,1674 NULL);1675 1676 if (!vpif_obj.sd[i]) {1677 vpif_err("Error registering v4l2 subdevice\n");1678 err = -ENODEV;1679 goto probe_subdev_out;1680 }1681 v4l2_info(&vpif_obj.v4l2_dev,1682 "registered sub device %s\n",1683 subdevdata->name);1684 }1685 err = vpif_probe_complete();1686 if (err)1687 goto probe_subdev_out;1688 } else {1689 vpif_obj.notifier.ops = &vpif_async_ops;1690 err = v4l2_async_nf_register(&vpif_obj.notifier);1691 if (err) {1692 vpif_err("Error registering async notifier\n");1693 err = -EINVAL;1694 goto probe_subdev_out;1695 }1696 }1697 1698 return 0;1699 1700probe_subdev_out:1701 v4l2_async_nf_cleanup(&vpif_obj.notifier);1702 /* free sub devices memory */1703 kfree(vpif_obj.sd);1704vpif_unregister:1705 v4l2_device_unregister(&vpif_obj.v4l2_dev);1706vpif_free:1707 free_vpif_objs();1708 1709 return err;1710}1711 1712/**1713 * vpif_remove() - driver remove handler1714 * @device: ptr to platform device structure1715 *1716 * The vidoe device is unregistered1717 */1718static void vpif_remove(struct platform_device *device)1719{1720 struct channel_obj *ch;1721 int i;1722 1723 v4l2_async_nf_unregister(&vpif_obj.notifier);1724 v4l2_async_nf_cleanup(&vpif_obj.notifier);1725 v4l2_device_unregister(&vpif_obj.v4l2_dev);1726 1727 kfree(vpif_obj.sd);1728 /* un-register device */1729 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {1730 /* Get the pointer to the channel object */1731 ch = vpif_obj.dev[i];1732 /* Unregister video device */1733 video_unregister_device(&ch->video_dev);1734 kfree(vpif_obj.dev[i]);1735 }1736}1737 1738#ifdef CONFIG_PM_SLEEP1739/**1740 * vpif_suspend: vpif device suspend1741 * @dev: pointer to &struct device1742 */1743static int vpif_suspend(struct device *dev)1744{1745 1746 struct common_obj *common;1747 struct channel_obj *ch;1748 int i;1749 1750 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {1751 /* Get the pointer to the channel object */1752 ch = vpif_obj.dev[i];1753 common = &ch->common[VPIF_VIDEO_INDEX];1754 1755 if (!vb2_start_streaming_called(&common->buffer_queue))1756 continue;1757 1758 mutex_lock(&common->lock);1759 /* Disable channel */1760 if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {1761 enable_channel0(0);1762 channel0_intr_enable(0);1763 }1764 if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||1765 ycmux_mode == 2) {1766 enable_channel1(0);1767 channel1_intr_enable(0);1768 }1769 mutex_unlock(&common->lock);1770 }1771 1772 return 0;1773}1774 1775/*1776 * vpif_resume: vpif device suspend1777 */1778static int vpif_resume(struct device *dev)1779{1780 struct common_obj *common;1781 struct channel_obj *ch;1782 int i;1783 1784 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {1785 /* Get the pointer to the channel object */1786 ch = vpif_obj.dev[i];1787 common = &ch->common[VPIF_VIDEO_INDEX];1788 1789 if (!vb2_start_streaming_called(&common->buffer_queue))1790 continue;1791 1792 mutex_lock(&common->lock);1793 /* Enable channel */1794 if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {1795 enable_channel0(1);1796 channel0_intr_enable(1);1797 }1798 if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||1799 ycmux_mode == 2) {1800 enable_channel1(1);1801 channel1_intr_enable(1);1802 }1803 mutex_unlock(&common->lock);1804 }1805 1806 return 0;1807}1808#endif1809 1810static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume);1811 1812static __refdata struct platform_driver vpif_driver = {1813 .driver = {1814 .name = VPIF_DRIVER_NAME,1815 .pm = &vpif_pm_ops,1816 },1817 .probe = vpif_probe,1818 .remove_new = vpif_remove,1819};1820 1821module_platform_driver(vpif_driver);1822