brintos

brintos / linux-shallow public Read only

0
0
Text · 48.2 KiB · 1632643 Raw
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