1efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/*
2efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * This is the driver for the STA2x11 Video Input Port.
3efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
48dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * Copyright (C) 2012       ST Microelectronics
58dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga *     author: Federico Vaga <federico.vaga@gmail.com>
6efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Copyright (C) 2010       WindRiver Systems, Inc.
78dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga *     authors: Andreas Kies <andreas.kies@windriver.com>
88dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga *              Vlad Lungu   <vlad.lungu@windriver.com>
9efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
10efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * This program is free software; you can redistribute it and/or modify it
11efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * under the terms and conditions of the GNU General Public License,
12efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * version 2, as published by the Free Software Foundation.
13efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
14efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * This program is distributed in the hope it will be useful, but WITHOUT
15efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * more details.
18efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
19efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * You should have received a copy of the GNU General Public License along with
20efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * this program; if not, write to the Free Software Foundation, Inc.,
21efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
23efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * The full GNU General Public License is included in this distribution in
24efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the file called "COPYING".
25efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
26efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
27efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
28efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/types.h>
29efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/kernel.h>
30efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/module.h>
31efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/init.h>
32efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/videodev2.h>
33efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/kmod.h>
34efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/pci.h>
35efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/interrupt.h>
36efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/io.h>
37efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/gpio.h>
38efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/i2c.h>
39efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/delay.h>
40efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <media/v4l2-common.h>
41efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <media/v4l2-device.h>
428dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga#include <media/v4l2-ctrls.h>
43efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <media/v4l2-ioctl.h>
448dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga#include <media/v4l2-fh.h>
458dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga#include <media/v4l2-event.h>
468dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga#include <media/videobuf2-dma-contig.h>
47efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
48efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include "sta2x11_vip.h"
49efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
50efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DRV_VERSION "1.3"
51efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
52efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifndef PCI_DEVICE_ID_STMICRO_VIP
53efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define PCI_DEVICE_ID_STMICRO_VIP 0xCC0D
54efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif
55efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
56efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define MAX_FRAMES 4
57efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
58efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/*Register offsets*/
59efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_CTL		0x00
60efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_TFO		0x04
61efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_TFS		0x08
62efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_BFO		0x0C
63efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_BFS		0x10
648dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga#define DVP_VTP		0x14
658dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga#define DVP_VBP		0x18
66efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_VMP		0x1C
67efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_ITM		0x98
68efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_ITS		0x9C
69efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_STA		0xA0
70efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_HLFLN	0xA8
71efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_RGB		0xC0
72efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_PKZ		0xF0
73efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
74efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/*Register fields*/
75efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_CTL_ENA	0x00000001
76efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_CTL_RST	0x80000000
77efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_CTL_DIS	(~0x00040001)
78efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
79efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_IT_VSB	0x00000008
80efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_IT_VST	0x00000010
81efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_IT_FIFO	0x00000020
82efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
83efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_HLFLN_SD	0x00000001
84efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
85efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define SAVE_COUNT 8
86efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define AUX_COUNT 3
87efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define IRQ_COUNT 1
88efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
898dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastruct vip_buffer {
918dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct vb2_buffer	vb;
928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct list_head	list;
938dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	dma_addr_t		dma;
948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga};
958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic inline struct vip_buffer *to_vip_buffer(struct vb2_buffer *vb2)
968dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{
978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	return container_of(vb2, struct vip_buffer, vb);
988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
998dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
100efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
101efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * struct sta2x11_vip - All internal data for one instance of device
102efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @v4l2_dev: device registered in v4l layer
103efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @video_dev: properties of our device
104efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device
105efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @adapter: contains I2C adapter information
106efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @register_save_area: All relevant register are saved here during suspend
107efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @decoder: contains information about video DAC
1088dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @ctrl_hdl: handler for control framework
109efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @format: pixel format, fixed UYVY
110efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: video standard (e.g. PAL/NTSC)
111efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @input: input line for video signal ( 0 or 1 )
112efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @disabled: Device is in power down state
113efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @slock: for excluse acces of registers
1148dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @alloc_ctx: context for videobuf2
1158dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @vb_vidq: queue maintained by videobuf2 layer
1168dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @buffer_list: list of buffer in use
1178dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @sequence: sequence number of acquired buffer
1188dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @active: current active buffer
1198dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @lock: used in videobuf2 callback
120efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @tcount: Number of top frames
121efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @bcount: Number of bottom frames
122efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @overflow: Number of FIFO overflows
123efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @iomem: hardware base address
124efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @config: I2C and gpio config from platform
125efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
126efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * All non-local data is accessed via this structure.
127efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
128efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastruct sta2x11_vip {
129efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_device v4l2_dev;
130efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *video_dev;
131efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct pci_dev *pdev;
132efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct i2c_adapter *adapter;
133efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	unsigned int register_save_area[IRQ_COUNT + SAVE_COUNT + AUX_COUNT];
134efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_subdev *decoder;
1358dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct v4l2_ctrl_handler ctrl_hdl;
1368dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
1378dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
138efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_pix_format format;
139efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	v4l2_std_id std;
140efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	unsigned int input;
141efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int disabled;
1428dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spinlock_t slock;
1438dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
1448dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct vb2_alloc_ctx *alloc_ctx;
1458dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct vb2_queue vb_vidq;
1468dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct list_head buffer_list;
1478dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	unsigned int sequence;
1488dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct vip_buffer *active; /* current active buffer */
1498dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spinlock_t lock; /* Used in videobuf2 callback */
1508dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
1518dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Interrupt counters */
1528dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	int tcount, bcount;
153efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int overflow;
1548dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
15587f4ebcd0693f6de14f60cf7bf9821a005b5850fMauro Carvalho Chehab	void __iomem *iomem;	/* I/O Memory */
156efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct vip_config *config;
157efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
158efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
159efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic const unsigned int registers_to_save[AUX_COUNT] = {
160efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	DVP_HLFLN, DVP_RGB, DVP_PKZ
161efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
162efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
163efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct v4l2_pix_format formats_50[] = {
164efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*PAL interlaced */
165efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
166efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 576,
167efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
168efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_INTERLACED,
169efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
170efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 576,
171efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
172efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*PAL top */
173efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
174efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 288,
175efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
176efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_TOP,
177efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
178efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 288,
179efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
180efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*PAL bottom */
181efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
182efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 288,
183efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
184efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_BOTTOM,
185efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
186efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 288,
187efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
188efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
189efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
190efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
191efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct v4l2_pix_format formats_60[] = {
192efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*NTSC interlaced */
193efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
194efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 480,
195efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
196efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_INTERLACED,
197efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
198efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 480,
199efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
200efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*NTSC top */
201efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
202efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 240,
203efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
204efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_TOP,
205efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
206efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 240,
207efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
208efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*NTSC bottom */
209efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
210efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 240,
211efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
212efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_BOTTOM,
213efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
214efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 240,
215efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
216efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
217efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
2188dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga/* Write VIP register */
2198dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic inline void reg_write(struct sta2x11_vip *vip, unsigned int reg, u32 val)
220efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
2218dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	iowrite32((val), (vip->iomem)+(reg));
2228dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
2238dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga/* Read VIP register */
2248dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic inline u32 reg_read(struct sta2x11_vip *vip, unsigned int reg)
225efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
2268dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	return  ioread32((vip->iomem)+(reg));
227efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
2288dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga/* Start DMA acquisition */
2298dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic void start_dma(struct sta2x11_vip *vip, struct vip_buffer *vip_buf)
230efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
2318dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	unsigned long offset = 0;
2328dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
2338dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (vip->format.field == V4L2_FIELD_INTERLACED)
2348dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		offset = vip->format.width * 2;
235efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
2368dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_lock_irq(&vip->slock);
2378dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Enable acquisition */
2388dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_CTL, reg_read(vip, DVP_CTL) | DVP_CTL_ENA);
2398dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Set Top and Bottom Field memory address */
2408dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_VTP, (u32)vip_buf->dma);
2418dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_VBP, (u32)vip_buf->dma + offset);
2428dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_unlock_irq(&vip->slock);
2438dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
244efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
2458dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga/* Fetch the next buffer to activate */
2468dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic void vip_active_buf_next(struct sta2x11_vip *vip)
2478dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{
2488dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Get the next buffer */
2498dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_lock(&vip->lock);
2508dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (list_empty(&vip->buffer_list)) {/* No available buffer */
2518dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		spin_unlock(&vip->lock);
252efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return;
253efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
2548dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->active = list_first_entry(&vip->buffer_list,
2558dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga				       struct vip_buffer,
2568dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga				       list);
2578dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Reset Top and Bottom counter */
258efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->tcount = 0;
259efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->bcount = 0;
2608dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_unlock(&vip->lock);
2618dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (vb2_is_streaming(&vip->vb_vidq)) {	/* streaming is on */
2628dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		start_dma(vip, vip->active);	/* start dma capture */
2638dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	}
2648dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
265efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
266efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
2678dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga/* Videobuf2 Operations */
2688dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
2698dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		       unsigned int *nbuffers, unsigned int *nplanes,
2708dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		       unsigned int sizes[], void *alloc_ctxs[])
2718dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{
2728dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = vb2_get_drv_priv(vq);
273efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
2748dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (!(*nbuffers) || *nbuffers < MAX_FRAMES)
2758dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		*nbuffers = MAX_FRAMES;
276efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
2778dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	*nplanes = 1;
2788dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	sizes[0] = vip->format.sizeimage;
2798dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	alloc_ctxs[0] = vip->alloc_ctx;
280efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
2818dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->sequence = 0;
2828dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->active = NULL;
2838dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->tcount = 0;
2848dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->bcount = 0;
285efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
2868dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	return 0;
2878dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga};
2888dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int buffer_init(struct vb2_buffer *vb)
289efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
2908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct vip_buffer *vip_buf = to_vip_buffer(vb);
291efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
2928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip_buf->dma = vb2_dma_contig_plane_dma_addr(vb, 0);
2938dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	INIT_LIST_HEAD(&vip_buf->list);
2948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	return 0;
295efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
296efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
2978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int buffer_prepare(struct vb2_buffer *vb)
298efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
2998dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = vb2_get_drv_priv(vb->vb2_queue);
3008dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct vip_buffer *vip_buf = to_vip_buffer(vb);
3018dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	unsigned long size;
3028dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
3038dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	size = vip->format.sizeimage;
3048dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (vb2_plane_size(vb, 0) < size) {
3058dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		v4l2_err(&vip->v4l2_dev, "buffer too small (%lu < %lu)\n",
3068dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga			 vb2_plane_size(vb, 0), size);
3078dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		return -EINVAL;
3088dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	}
309efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
3108dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vb2_set_plane_payload(&vip_buf->vb, 0, size);
311efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
3128dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	return 0;
3138dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
3148dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic void buffer_queue(struct vb2_buffer *vb)
3158dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{
3168dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = vb2_get_drv_priv(vb->vb2_queue);
3178dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct vip_buffer *vip_buf = to_vip_buffer(vb);
3188dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
3198dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_lock(&vip->lock);
3208dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	list_add_tail(&vip_buf->list, &vip->buffer_list);
3218dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (!vip->active) {	/* No active buffer, active the first one */
3228dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		vip->active = list_first_entry(&vip->buffer_list,
3238dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga					       struct vip_buffer,
3248dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga					       list);
3258dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		if (vb2_is_streaming(&vip->vb_vidq))	/* streaming is on */
3268dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga			start_dma(vip, vip_buf);	/* start dma capture */
327efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
3288dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_unlock(&vip->lock);
3298dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
3300647064293d745720fc62e2edc7734fa8af06adfHans Verkuilstatic void buffer_finish(struct vb2_buffer *vb)
3318dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{
3328dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = vb2_get_drv_priv(vb->vb2_queue);
3338dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct vip_buffer *vip_buf = to_vip_buffer(vb);
334efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
3358dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Buffer handled, remove it from the list */
3368dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_lock(&vip->lock);
3378dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	list_del_init(&vip_buf->list);
3388dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_unlock(&vip->lock);
339efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
3409c0863b1cc485f2bacac0675c68b73e5341cfd26Hans Verkuil	if (vb2_is_streaming(vb->vb2_queue))
3419c0863b1cc485f2bacac0675c68b73e5341cfd26Hans Verkuil		vip_active_buf_next(vip);
342efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
343efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
3448dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int start_streaming(struct vb2_queue *vq, unsigned int count)
345efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
3468dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = vb2_get_drv_priv(vq);
347efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
348efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_lock_irq(&vip->slock);
3498dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Enable interrupt VSYNC Top and Bottom*/
3508dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_ITM, DVP_IT_VSB | DVP_IT_VST);
351efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_unlock_irq(&vip->slock);
352efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
3538dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (count)
3548dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		start_dma(vip, vip->active);
355efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
356efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
357efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
358efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
3598dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga/* abort streaming and wait for last buffer */
360e37559b22c63b557d242bfa1a07ab1b8f7d5d9f1Hans Verkuilstatic void stop_streaming(struct vb2_queue *vq)
361efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
3628dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = vb2_get_drv_priv(vq);
3638dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct vip_buffer *vip_buf, *node;
3648dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
3658dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Disable acquisition */
3668dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_CTL, reg_read(vip, DVP_CTL) & ~DVP_CTL_ENA);
3678dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Disable all interrupts */
3688dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_ITM, 0);
3698dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
3708dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Release all active buffers */
3718dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_lock(&vip->lock);
3728dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	list_for_each_entry_safe(vip_buf, node, &vip->buffer_list, list) {
3738dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		vb2_buffer_done(&vip_buf->vb, VB2_BUF_STATE_ERROR);
3748dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		list_del(&vip_buf->list);
3758dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	}
3768dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_unlock(&vip->lock);
377efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
378efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
3798dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic struct vb2_ops vip_video_qops = {
3808dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.queue_setup		= queue_setup,
3818dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.buf_init		= buffer_init,
3828dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.buf_prepare		= buffer_prepare,
3838dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.buf_finish		= buffer_finish,
3848dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.buf_queue		= buffer_queue,
3858dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.start_streaming	= start_streaming,
3868dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.stop_streaming		= stop_streaming,
3878dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga};
388efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
389efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
3908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga/* File Operations */
3918dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic const struct v4l2_file_operations vip_fops = {
3928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.owner = THIS_MODULE,
3938dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.open = v4l2_fh_open,
3948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.release = vb2_fop_release,
3958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.unlocked_ioctl = video_ioctl2,
3968dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.read = vb2_fop_read,
3978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.mmap = vb2_fop_mmap,
3988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.poll = vb2_fop_poll
3998dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga};
400efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
401efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
402efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
403efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_querycap - return capabilities of device
4048dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device
405efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @cap: contains return values
406efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
407efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the capabilities of the device are returned
408efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
409efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
410efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
411efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_querycap(struct file *file, void *priv,
412efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			   struct v4l2_capability *cap)
413efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
4148dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = video_drvdata(file);
415efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
4168dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	strcpy(cap->driver, KBUILD_MODNAME);
4178dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	strcpy(cap->card, KBUILD_MODNAME);
418efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
419efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 pci_name(vip->pdev));
4208dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
4218dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga			   V4L2_CAP_STREAMING;
4228dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
423efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
424efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
425efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
426efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
427efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
428efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_s_std - set video standard
4298dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device
430efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: contains standard to be set
431efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
432efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the video standard is set
433efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
434efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
435efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
436efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EIO, no input signal detected
437efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
438efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other, returned from video DAC.
439efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
440314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuilstatic int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
441efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
4428dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = video_drvdata(file);
443efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	v4l2_std_id oldstd = vip->std, newstd;
444efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int status;
445efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
446314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil	if (V4L2_STD_ALL == std) {
4478774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart		v4l2_subdev_call(vip->decoder, video, s_std, std);
448efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ssleep(2);
449efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		v4l2_subdev_call(vip->decoder, video, querystd, &newstd);
450efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		v4l2_subdev_call(vip->decoder, video, g_input_status, &status);
451efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (status & V4L2_IN_ST_NO_SIGNAL)
452efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			return -EIO;
453314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil		std = vip->std = newstd;
454314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil		if (oldstd != std) {
455314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil			if (V4L2_STD_525_60 & std)
456efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				vip->format = formats_60[0];
457efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			else
458efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				vip->format = formats_50[0];
459efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		}
460efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return 0;
461efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
462efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
463314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil	if (oldstd != std) {
464314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil		if (V4L2_STD_525_60 & std)
465efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			vip->format = formats_60[0];
466efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		else
467efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			vip->format = formats_50[0];
468efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
469efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
4708774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart	return v4l2_subdev_call(vip->decoder, video, s_std, std);
471efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
472efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
473efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
474efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_g_std - get video standard
4758dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device
476efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: contains return values
477efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
478efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the current video standard is returned
479efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
480efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
481efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
482efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
483efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
4848dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = video_drvdata(file);
485efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
486efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	*std = vip->std;
487efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
488efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
489efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
490efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
491efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_querystd - get possible video standards
4928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device
493efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: contains return values
494efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
495efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * all possible video standards are returned
496efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
497efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: delivered by video DAC routine.
498efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
499efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
500efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
5018dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = video_drvdata(file);
502efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
503efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return v4l2_subdev_call(vip->decoder, video, querystd, std);
504efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
505efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
506efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_enum_input(struct file *file, void *priv,
507efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			     struct v4l2_input *inp)
508efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
509efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (inp->index > 1)
510efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EINVAL;
511efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
512efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	inp->type = V4L2_INPUT_TYPE_CAMERA;
513efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	inp->std = V4L2_STD_ALL;
514efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	sprintf(inp->name, "Camera %u", inp->index);
515efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
516efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
517efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
518efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
519efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
520efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_s_input - set input line
5218dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device
522efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @i: new input line number
523efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
524efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the current active input line is set
525efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
526efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
527efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
528efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EINVAL, line number out of range
529efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
530efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_s_input(struct file *file, void *priv, unsigned int i)
531efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
5328dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = video_drvdata(file);
533efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret;
534efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
535efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (i > 1)
536efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EINVAL;
537efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = v4l2_subdev_call(vip->decoder, video, s_routing, i, 0, 0);
538efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
539efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!ret)
540efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->input = i;
541efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
542efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
543efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
544efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
545efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
546efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_g_input - return input line
5478dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device
548efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @i: returned input line number
549efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
550efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the current active input line is returned
551efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
552efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: always 0.
553efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
554efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
555efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
5568dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = video_drvdata(file);
557efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
558efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	*i = vip->input;
559efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
560efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
561efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
562efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
563efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_enum_fmt_vid_cap - return video capture format
564efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: returned format information
565efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
566efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * returns name and format of video capture
567efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Only UYVY is supported by hardware.
568efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
569efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: always 0.
570efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
571efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
572efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				   struct v4l2_fmtdesc *f)
573efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
574efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
575efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (f->index != 0)
576efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EINVAL;
577efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
578efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	strcpy(f->description, "4:2:2, packed, UYVY");
579efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->pixelformat = V4L2_PIX_FMT_UYVY;
580efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->flags = 0;
581efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
582efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
583efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
584efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
585efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_try_fmt_vid_cap - set video capture format
5868dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device
587efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: new format
588efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
589efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * new video format is set which includes width and
590efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * field type. width is fixed to 720, no scaling.
591efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Only UYVY is supported by this hardware.
592efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the minimum height is 200, the maximum is 576 (PAL)
593efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
594efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error
595efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
596efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EINVAL, pixel or field format not supported
597efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
598efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
599efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
600efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				  struct v4l2_format *f)
601efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
6028dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = video_drvdata(file);
603efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int interlace_lim;
604efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
6058dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (V4L2_PIX_FMT_UYVY != f->fmt.pix.pixelformat) {
6068dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		v4l2_warn(&vip->v4l2_dev, "Invalid format, only UYVY supported\n");
607efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EINVAL;
6088dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	}
609efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
6106ae009a8ba512d5b07386bbb1172cfd7a02986aaMauro Carvalho Chehab	if (V4L2_STD_525_60 & vip->std)
611efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		interlace_lim = 240;
612efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	else
613efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		interlace_lim = 288;
614efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
615efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	switch (f->fmt.pix.field) {
6168dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	default:
617efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_ANY:
618efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (interlace_lim < f->fmt.pix.height)
619efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			f->fmt.pix.field = V4L2_FIELD_INTERLACED;
620efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		else
621efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			f->fmt.pix.field = V4L2_FIELD_BOTTOM;
622efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		break;
623efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_TOP:
624efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_BOTTOM:
625efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (interlace_lim < f->fmt.pix.height)
626efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			f->fmt.pix.height = interlace_lim;
627efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		break;
628efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_INTERLACED:
629efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		break;
630efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
631efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
6328dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* It is the only supported format */
6338dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
634efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.height &= ~1;
635efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (2 * interlace_lim < f->fmt.pix.height)
636efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		f->fmt.pix.height = 2 * interlace_lim;
637efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (200 > f->fmt.pix.height)
638efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		f->fmt.pix.height = 200;
639efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.width = 720;
640efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
641efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.sizeimage = f->fmt.pix.width * 2 * f->fmt.pix.height;
642efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
643efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
644efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
645efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
646efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
647efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_s_fmt_vid_cap - set current video format parameters
6488dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device
649efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: returned format information
650efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
651efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * set new capture format
652efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error
653efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
654efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other, delivered by video DAC routine.
655efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
656efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
657efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				struct v4l2_format *f)
658efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
6598dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = video_drvdata(file);
6608dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	unsigned int t_stop, b_stop, pitch;
661efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret;
662efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
663efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = vidioc_try_fmt_vid_cap(file, priv, f);
664efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret)
665efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
666efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
6678dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (vb2_is_busy(&vip->vb_vidq)) {
6688dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		/* Can't change format during acquisition */
6698dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		v4l2_err(&vip->v4l2_dev, "device busy\n");
6708dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		return -EBUSY;
6718dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	}
6728dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->format = f->fmt.pix;
6738dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	switch (vip->format.field) {
6748dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	case V4L2_FIELD_INTERLACED:
6758dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		t_stop = ((vip->format.height / 2 - 1) << 16) |
6768dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga			 (2 * vip->format.width - 1);
6778dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		b_stop = t_stop;
6788dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		pitch = 4 * vip->format.width;
6798dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		break;
6808dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	case V4L2_FIELD_TOP:
6818dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		t_stop = ((vip->format.height - 1) << 16) |
6828dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga			 (2 * vip->format.width - 1);
6838dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		b_stop = (0 << 16) | (2 * vip->format.width - 1);
6848dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		pitch = 2 * vip->format.width;
6858dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		break;
6868dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	case V4L2_FIELD_BOTTOM:
6878dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		t_stop = (0 << 16) | (2 * vip->format.width - 1);
6888dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		b_stop = (vip->format.height << 16) |
6898dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga			 (2 * vip->format.width - 1);
6908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		pitch = 2 * vip->format.width;
6918dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		break;
6928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	default:
6938dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		v4l2_err(&vip->v4l2_dev, "unknown field format\n");
6948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		return -EINVAL;
6958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	}
6968dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
6978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_lock_irq(&vip->slock);
6988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Y-X Top Field Offset */
6998dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_TFO, 0);
7008dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Y-X Bottom Field Offset */
7018dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_BFO, 0);
7028dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Y-X Top Field Stop*/
7038dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_TFS, t_stop);
7048dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Y-X Bottom Field Stop */
7058dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_BFS, b_stop);
7068dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Video Memory Pitch */
7078dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_VMP, pitch);
7088dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_unlock_irq(&vip->slock);
7098dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
710efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
711efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
712efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
713efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
714efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_g_fmt_vid_cap - get current video format parameters
7158dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device
716efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: contains format information
717efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
718efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * returns current video format parameters
719efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
720efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, always successful
721efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
722efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
723efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				struct v4l2_format *f)
724efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
7258dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	struct sta2x11_vip *vip = video_drvdata(file);
726efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
7278dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	f->fmt.pix = vip->format;
728efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
7298dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	return 0;
730efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
731efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
732efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic const struct v4l2_ioctl_ops vip_ioctl_ops = {
733efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_querycap = vidioc_querycap,
7348dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* FMT handling */
7358dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
7368dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
7378dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
7388dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
7398dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Buffer handlers */
7408dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_create_bufs = vb2_ioctl_create_bufs,
7418dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
7428dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_reqbufs = vb2_ioctl_reqbufs,
7438dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_querybuf = vb2_ioctl_querybuf,
7448dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_qbuf = vb2_ioctl_qbuf,
7458dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_dqbuf = vb2_ioctl_dqbuf,
7468dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Stream on/off */
7478dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_streamon = vb2_ioctl_streamon,
7488dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_streamoff = vb2_ioctl_streamoff,
7498dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Standard handling */
750efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_g_std = vidioc_g_std,
7518dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_s_std = vidioc_s_std,
752efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_querystd = vidioc_querystd,
7538dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Input handling */
754efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_enum_input = vidioc_enum_input,
755efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_g_input = vidioc_g_input,
7568dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_s_input = vidioc_s_input,
7578dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Log status ioctl */
7588dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_log_status = v4l2_ctrl_log_status,
7598dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Event handling */
7608dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
7618dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
762efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
763efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
764efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct video_device video_dev_template = {
7658dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.name = KBUILD_MODNAME,
766efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.release = video_device_release,
767efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.fops = &vip_fops,
768efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.ioctl_ops = &vip_ioctl_ops,
769efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.tvnorms = V4L2_STD_ALL,
770efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
771efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
772efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
773efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_irq - interrupt routine
774efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @irq: Number of interrupt ( not used, correct number is assumed )
775efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vip: local data structure containing all information
776efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
777efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * check for both frame interrupts set ( top and bottom ).
778efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * check FIFO overflow, but limit number of log messages after open.
7798dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * signal a complete buffer if done
780efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
781efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: IRQ_NONE, interrupt was not generated by VIP
782efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
783efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * IRQ_HANDLED, interrupt done.
784efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
785efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
786efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
7878dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	unsigned int status;
788efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
7898dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	status = reg_read(vip, DVP_ITS);
790efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
7918dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (!status)		/* No interrupt to handle */
792efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return IRQ_NONE;
793efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
7948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (status & DVP_IT_FIFO)
7958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		if (vip->overflow++ > 5)
7968dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga			pr_info("VIP: fifo overflow\n");
797efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
7988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if ((status & DVP_IT_VST) && (status & DVP_IT_VSB)) {
799efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		/* this is bad, we are too slow, hope the condition is gone
800efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 * on the next frame */
801efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return IRQ_HANDLED;
802efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
803efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
8048dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (status & DVP_IT_VST)
8058dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		if ((++vip->tcount) < 2)
8068dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga			return IRQ_HANDLED;
8078dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (status & DVP_IT_VSB) {
8088dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		vip->bcount++;
8098dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		return IRQ_HANDLED;
810efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
811efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
8128dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (vip->active) { /* Acquisition is over on this buffer */
8138dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		/* Disable acquisition */
8148dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		reg_write(vip, DVP_CTL, reg_read(vip, DVP_CTL) & ~DVP_CTL_ENA);
8158dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		/* Remove the active buffer from the list */
8168dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		do_gettimeofday(&vip->active->vb.v4l2_buf.timestamp);
8178dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		vip->active->vb.v4l2_buf.sequence = vip->sequence++;
8188dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		vb2_buffer_done(&vip->active->vb, VB2_BUF_STATE_DONE);
8198dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	}
820efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
8218dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	return IRQ_HANDLED;
8228dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
823efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
8248dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic void sta2x11_vip_init_register(struct sta2x11_vip *vip)
8258dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{
8268dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Register initialization */
8278dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_lock_irq(&vip->slock);
8288dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Clean interrupt */
8298dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_read(vip, DVP_ITS);
8308dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Enable Half Line per vertical */
8318dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_HLFLN, DVP_HLFLN_SD);
8328dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Reset VIP control */
8338dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_CTL, DVP_CTL_RST);
8348dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Clear VIP control */
8358dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_CTL, 0);
8368dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_unlock_irq(&vip->slock);
8378dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
8388dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic void sta2x11_vip_clear_register(struct sta2x11_vip *vip)
8398dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{
8408dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_lock_irq(&vip->slock);
8418dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Disable interrupt */
8428dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_ITM, 0);
8438dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Reset VIP Control */
8448dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_CTL, DVP_CTL_RST);
8458dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Clear VIP Control */
8468dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_CTL, 0);
8478dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Clean VIP Interrupt */
8488dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_read(vip, DVP_ITS);
8498dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_unlock_irq(&vip->slock);
8508dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
8518dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int sta2x11_vip_init_buffer(struct sta2x11_vip *vip)
8528dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{
8538dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	int err;
854efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
8558dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	err = dma_set_coherent_mask(&vip->pdev->dev, DMA_BIT_MASK(29));
8568dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (err) {
8578dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		v4l2_err(&vip->v4l2_dev, "Cannot configure coherent mask");
8588dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		return err;
859efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
8608dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	memset(&vip->vb_vidq, 0, sizeof(struct vb2_queue));
8618dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->vb_vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
8628dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->vb_vidq.io_modes = VB2_MMAP | VB2_READ;
8638dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->vb_vidq.drv_priv = vip;
8648dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->vb_vidq.buf_struct_size = sizeof(struct vip_buffer);
8658dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->vb_vidq.ops = &vip_video_qops;
8668dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->vb_vidq.mem_ops = &vb2_dma_contig_memops;
8678dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	err = vb2_queue_init(&vip->vb_vidq);
8688dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (err)
8698dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		return err;
8708dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	INIT_LIST_HEAD(&vip->buffer_list);
8718dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	spin_lock_init(&vip->lock);
8728dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
8738dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
8748dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->alloc_ctx = vb2_dma_contig_init_ctx(&vip->pdev->dev);
8758dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (IS_ERR(vip->alloc_ctx)) {
8768dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		v4l2_err(&vip->v4l2_dev, "Can't allocate buffer context");
8778dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		return PTR_ERR(vip->alloc_ctx);
878efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
8798dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
8808dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	return 0;
8818dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
8828dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic void sta2x11_vip_release_buffer(struct sta2x11_vip *vip)
8838dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{
8848dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vb2_dma_contig_cleanup_ctx(vip->alloc_ctx);
8858dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}
8868dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int sta2x11_vip_init_controls(struct sta2x11_vip *vip)
8878dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{
8888dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/*
8898dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	 * Inititialize an empty control so VIP can inerithing controls
8908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	 * from ADV7180
8918dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	 */
8928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	v4l2_ctrl_handler_init(&vip->ctrl_hdl, 0);
8938dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
8948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->v4l2_dev.ctrl_handler = &vip->ctrl_hdl;
8958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (vip->ctrl_hdl.error) {
8968dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		int err = vip->ctrl_hdl.error;
8978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
8988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		v4l2_ctrl_handler_free(&vip->ctrl_hdl);
8998dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		return err;
9008dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	}
9018dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
9028dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	return 0;
903efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
904efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
905efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
906efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_gpio_reserve - reserve gpio pin
907efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @dev: device
908efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pin: GPIO pin number
909efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @dir: direction, input or output
910efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @name: GPIO pin name
911efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
912efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
913efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vip_gpio_reserve(struct device *dev, int pin, int dir,
914efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			    const char *name)
915efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
916efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret;
917efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
918efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (pin == -1)
919efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return 0;
920efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
921efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = gpio_request(pin, name);
922efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret) {
923efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(dev, "Failed to allocate pin %d (%s)\n", pin, name);
924efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
925efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
926efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
927efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = gpio_direction_output(pin, dir);
928efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret) {
929efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(dev, "Failed to set direction for pin %d (%s)\n",
930efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			pin, name);
931efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		gpio_free(pin);
932efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
933efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
934efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
935efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = gpio_export(pin, false);
936efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret) {
937efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(dev, "Failed to export pin %d (%s)\n", pin, name);
938efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		gpio_free(pin);
939efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
940efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
941efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
942efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
943efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
944efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
945efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
946efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_gpio_release - release gpio pin
947efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @dev: device
948efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pin: GPIO pin number
949efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @name: GPIO pin name
950efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
951efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
952efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic void vip_gpio_release(struct device *dev, int pin, const char *name)
953efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
954efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (pin != -1) {
955efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_dbg(dev, "releasing pin %d (%s)\n",	pin, name);
956efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		gpio_unexport(pin);
957efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		gpio_free(pin);
958efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
959efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
960efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
961efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
962efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_init_one - init one instance of video device
963efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device
964efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @ent: (not used)
965efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
966efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * allocate reset pins for DAC.
967efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Reset video DAC, this is done via reset line.
968efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * allocate memory for managing device
969efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * request interrupt
970efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * map IO region
971efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * register device
972efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * find and initialize video DAC
973efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
974efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error
975efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
976efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -ENOMEM, no memory
977efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
978efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -ENODEV, device could not be detected or registered
979efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
9804c62e9764ab403d42f9b8871b1241fe7812f19d4Greg Kroah-Hartmanstatic int sta2x11_vip_init_one(struct pci_dev *pdev,
9814c62e9764ab403d42f9b8871b1241fe7812f19d4Greg Kroah-Hartman				const struct pci_device_id *ent)
982efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
983efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret;
984efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip;
985efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct vip_config *config;
986efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
9878dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Check if hardware support 26-bit DMA */
9888dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(26))) {
9898dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		dev_err(&pdev->dev, "26-bit DMA addressing not available\n");
9908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		return -EINVAL;
9918dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	}
9928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Enable PCI */
993efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = pci_enable_device(pdev);
994efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret)
995efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
996efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
9978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Get VIP platform data */
998efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	config = dev_get_platdata(&pdev->dev);
999efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!config) {
1000efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_info(&pdev->dev, "VIP slot disabled\n");
1001efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -EINVAL;
1002efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto disable;
1003efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1004efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
10058dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Power configuration */
1006efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = vip_gpio_reserve(&pdev->dev, config->pwr_pin, 0,
1007efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			       config->pwr_name);
1008efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret)
1009efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto disable;
1010efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1011efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (config->reset_pin >= 0) {
1012efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = vip_gpio_reserve(&pdev->dev, config->reset_pin, 0,
1013efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				       config->reset_name);
1014efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (ret) {
1015efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			vip_gpio_release(&pdev->dev, config->pwr_pin,
1016efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					 config->pwr_name);
1017efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			goto disable;
1018efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		}
1019efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1020efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (config->pwr_pin != -1) {
1021efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		/* Datasheet says 5ms between PWR and RST */
1022efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		usleep_range(5000, 25000);
1023efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = gpio_direction_output(config->pwr_pin, 1);
1024efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1025efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1026efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (config->reset_pin != -1) {
1027efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		/* Datasheet says 5ms between PWR and RST */
1028efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		usleep_range(5000, 25000);
1029efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = gpio_direction_output(config->reset_pin, 1);
1030efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1031efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	usleep_range(5000, 25000);
1032efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
10338dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Allocate a new VIP instance */
1034efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip = kzalloc(sizeof(struct sta2x11_vip), GFP_KERNEL);
1035efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip) {
1036efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENOMEM;
1037efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto release_gpios;
1038efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1039efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->pdev = pdev;
1040efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->std = V4L2_STD_PAL;
1041efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->format = formats_50[0];
1042efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->config = config;
1043efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
10448dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	ret = sta2x11_vip_init_controls(vip);
10458dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (ret)
10468dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		goto free_mem;
1047d017650b40b4cb5c4158e3b9af38af164986b022Wei Yongjun	ret = v4l2_device_register(&pdev->dev, &vip->v4l2_dev);
1048d017650b40b4cb5c4158e3b9af38af164986b022Wei Yongjun	if (ret)
1049efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto free_mem;
1050efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1051efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	dev_dbg(&pdev->dev, "BAR #0 at 0x%lx 0x%lx irq %d\n",
1052efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		(unsigned long)pci_resource_start(pdev, 0),
1053efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		(unsigned long)pci_resource_len(pdev, 0), pdev->irq);
1054efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1055efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_set_master(pdev);
1056efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
10578dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	ret = pci_request_regions(pdev, KBUILD_MODNAME);
1058efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret)
1059efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto unreg;
1060efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1061efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->iomem = pci_iomap(pdev, 0, 0x100);
1062efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->iomem) {
10638dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		ret = -ENOMEM;
1064efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto release;
1065efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1066efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1067efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_enable_msi(pdev);
1068efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
10698dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Initialize buffer */
10708dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	ret = sta2x11_vip_init_buffer(vip);
10718dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	if (ret)
10728dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		goto unmap;
10738dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
1074efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_lock_init(&vip->slock);
1075efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1076efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = request_irq(pdev->irq,
1077efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  (irq_handler_t) vip_irq,
10788dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga			  IRQF_SHARED, KBUILD_MODNAME, vip);
1079efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret) {
1080efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(&pdev->dev, "request_irq failed\n");
1081efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENODEV;
10828dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		goto release_buf;
1083efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1084efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
10858dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Alloc, initialize and register video device */
1086efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->video_dev = video_device_alloc();
1087efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->video_dev) {
1088efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENOMEM;
1089efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto release_irq;
1090efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1091efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
10928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->video_dev = &video_dev_template;
10938dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->video_dev->v4l2_dev = &vip->v4l2_dev;
10948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->video_dev->queue = &vip->vb_vidq;
1095efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	video_set_drvdata(vip->video_dev, vip);
1096efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1097efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = video_register_device(vip->video_dev, VFL_TYPE_GRABBER, -1);
1098efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret)
1099efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto vrelease;
1100efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
11018dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	/* Get ADV7180 subdevice */
1102efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->adapter = i2c_get_adapter(vip->config->i2c_id);
1103efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->adapter) {
1104efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENODEV;
1105efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(&pdev->dev, "no I2C adapter found\n");
1106efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto vunreg;
1107efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1108efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1109efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->decoder = v4l2_i2c_new_subdev(&vip->v4l2_dev, vip->adapter,
1110efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					   "adv7180", vip->config->i2c_addr,
1111efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					   NULL);
1112efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->decoder) {
1113efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENODEV;
1114efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(&pdev->dev, "no decoder found\n");
1115efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto vunreg;
1116efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1117efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1118efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	i2c_put_adapter(vip->adapter);
1119efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	v4l2_subdev_call(vip->decoder, core, init, 0);
1120efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
11218dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	sta2x11_vip_init_register(vip);
11228dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
11238dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	dev_info(&pdev->dev, "STA2X11 Video Input Port (VIP) loaded\n");
1124efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
1125efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1126efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagavunreg:
1127efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	video_set_drvdata(vip->video_dev, NULL);
1128efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagavrelease:
1129efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (video_is_registered(vip->video_dev))
1130efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		video_unregister_device(vip->video_dev);
1131efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	else
1132efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		video_device_release(vip->video_dev);
1133efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagarelease_irq:
1134efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	free_irq(pdev->irq, vip);
11358dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagarelease_buf:
11368dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	sta2x11_vip_release_buffer(vip);
1137efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_disable_msi(pdev);
1138efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagaunmap:
11398dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vb2_queue_release(&vip->vb_vidq);
1140efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_iounmap(pdev, vip->iomem);
1141efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagarelease:
1142efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_release_regions(pdev);
1143efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagaunreg:
1144efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	v4l2_device_unregister(&vip->v4l2_dev);
1145efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagafree_mem:
1146efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	kfree(vip);
1147efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagarelease_gpios:
1148efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip_gpio_release(&pdev->dev, config->reset_pin, config->reset_name);
1149efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip_gpio_release(&pdev->dev, config->pwr_pin, config->pwr_name);
1150efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagadisable:
1151efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/*
1152efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 * do not call pci_disable_device on sta2x11 because it break all
1153efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 * other Bus masters on this EP
1154efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 */
1155efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return ret;
1156efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1157efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1158efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
1159efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_remove_one - release device
1160efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device
1161efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1162efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Undo everything done in .._init_one
1163efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1164efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * unregister video device
1165efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * free interrupt
1166efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * unmap ioadresses
1167efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * free memory
1168efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * free GPIO pins
1169efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
11704c62e9764ab403d42f9b8871b1241fe7812f19d4Greg Kroah-Hartmanstatic void sta2x11_vip_remove_one(struct pci_dev *pdev)
1171efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1172efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
1173efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip =
1174efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	    container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1175efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
11768dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	sta2x11_vip_clear_register(vip);
11778dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga
1178efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	video_set_drvdata(vip->video_dev, NULL);
1179efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	video_unregister_device(vip->video_dev);
1180efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/*do not call video_device_release() here, is already done */
1181efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	free_irq(pdev->irq, vip);
1182efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_disable_msi(pdev);
11838dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vb2_queue_release(&vip->vb_vidq);
1184efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_iounmap(pdev, vip->iomem);
1185efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_release_regions(pdev);
1186efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1187efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	v4l2_device_unregister(&vip->v4l2_dev);
1188efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1189efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip_gpio_release(&pdev->dev, vip->config->pwr_pin,
1190efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			 vip->config->pwr_name);
1191efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip_gpio_release(&pdev->dev, vip->config->reset_pin,
1192efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			 vip->config->reset_name);
1193efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1194efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	kfree(vip);
1195efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/*
1196efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 * do not call pci_disable_device on sta2x11 because it break all
1197efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 * other Bus masters on this EP
1198efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 */
1199efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1200efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1201efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifdef CONFIG_PM
1202efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1203efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
1204efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_suspend - set device into power save mode
1205efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device
1206efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @state: new state of device
1207efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1208efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * all relevant registers are saved and an attempt to set a new state is made.
1209efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1210efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0 always indicate success,
1211efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * even if device could not be disabled. (workaround for hardware problem)
1212efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
1213efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int sta2x11_vip_suspend(struct pci_dev *pdev, pm_message_t state)
1214efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1215efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
1216efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip =
1217efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	    container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1218efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	unsigned long flags;
1219efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int i;
1220efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1221efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_lock_irqsave(&vip->slock, flags);
12228dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->register_save_area[0] = reg_read(vip, DVP_CTL);
12238dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_CTL, vip->register_save_area[0] & DVP_CTL_DIS);
12248dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	vip->register_save_area[SAVE_COUNT] = reg_read(vip, DVP_ITM);
12258dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_ITM, 0);
1226efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	for (i = 1; i < SAVE_COUNT; i++)
12278dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		vip->register_save_area[i] = reg_read(vip, 4 * i);
1228efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	for (i = 0; i < AUX_COUNT; i++)
1229efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i] =
12308dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		    reg_read(vip, registers_to_save[i]);
1231efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_unlock_irqrestore(&vip->slock, flags);
1232efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/* save pci state */
1233efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_save_state(pdev);
1234efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (pci_set_power_state(pdev, pci_choose_state(pdev, state))) {
1235efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		/*
1236efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 * do not call pci_disable_device on sta2x11 because it
1237efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 * break all other Bus masters on this EP
1238efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 */
1239efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->disabled = 1;
1240efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1241efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1242efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pr_info("VIP: suspend\n");
1243efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
1244efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1245efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1246efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
1247efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_resume - resume device operation
1248efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev : PCI device
1249efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1250efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * re-enable device, set PCI state to powered and restore registers.
1251efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * resume normal device operation afterwards.
1252efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1253efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
1254efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1255efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other, could not set device to power on state.
1256efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
1257efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int sta2x11_vip_resume(struct pci_dev *pdev)
1258efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1259efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
1260efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip =
1261efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	    container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1262efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	unsigned long flags;
1263efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret, i;
1264efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1265efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pr_info("VIP: resume\n");
1266efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/* restore pci state */
1267efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (vip->disabled) {
1268efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = pci_enable_device(pdev);
1269efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (ret) {
12708dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga			pr_warn("VIP: Can't enable device.\n");
1271efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			return ret;
1272efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		}
1273efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->disabled = 0;
1274efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1275efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = pci_set_power_state(pdev, PCI_D0);
1276efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret) {
1277efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		/*
1278efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 * do not call pci_disable_device on sta2x11 because it
1279efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 * break all other Bus masters on this EP
1280efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 */
12818dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		pr_warn("VIP: Can't enable device.\n");
1282efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->disabled = 1;
1283efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
1284efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1285efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1286efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_restore_state(pdev);
1287efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1288efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_lock_irqsave(&vip->slock, flags);
1289efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	for (i = 1; i < SAVE_COUNT; i++)
12908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		reg_write(vip, 4 * i, vip->register_save_area[i]);
1291efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	for (i = 0; i < AUX_COUNT; i++)
12928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga		reg_write(vip, registers_to_save[i],
1293efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i]);
12948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_CTL, vip->register_save_area[0]);
12958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	reg_write(vip, DVP_ITM, vip->register_save_area[SAVE_COUNT]);
1296efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_unlock_irqrestore(&vip->slock, flags);
1297efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
1298efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1299efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1300efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif
1301efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1302f1b84d365af6d5ce1898fb7956e2053db14cc96eJingoo Hanstatic const struct pci_device_id sta2x11_vip_pci_tbl[] = {
1303efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIP)},
1304efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{0,}
1305efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
1306efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1307efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct pci_driver sta2x11_vip_driver = {
13088dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga	.name = KBUILD_MODNAME,
1309efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.probe = sta2x11_vip_init_one,
13104c62e9764ab403d42f9b8871b1241fe7812f19d4Greg Kroah-Hartman	.remove = sta2x11_vip_remove_one,
1311efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.id_table = sta2x11_vip_pci_tbl,
1312efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifdef CONFIG_PM
1313efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.suspend = sta2x11_vip_suspend,
1314efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.resume = sta2x11_vip_resume,
1315efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif
1316efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
1317efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1318efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int __init sta2x11_vip_init_module(void)
1319efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1320efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return pci_register_driver(&sta2x11_vip_driver);
1321efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1322efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1323efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic void __exit sta2x11_vip_exit_module(void)
1324efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1325efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_unregister_driver(&sta2x11_vip_driver);
1326efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1327efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1328efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifdef MODULE
1329efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagamodule_init(sta2x11_vip_init_module);
1330efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagamodule_exit(sta2x11_vip_exit_module);
1331efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#else
1332efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagalate_initcall_sync(sta2x11_vip_init_module);
1333efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif
1334efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1335efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_DESCRIPTION("STA2X11 Video Input Port driver");
1336efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_AUTHOR("Wind River");
1337efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_LICENSE("GPL v2");
1338efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_SUPPORTED_DEVICE("sta2x11 video input");
1339efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_VERSION(DRV_VERSION);
1340efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_DEVICE_TABLE(pci, sta2x11_vip_pci_tbl);
1341