sta2x11_vip.c revision 6ae009a8ba512d5b07386bbb1172cfd7a02986aa
1efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/*
2efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * This is the driver for the STA2x11 Video Input Port.
3efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
4efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Copyright (C) 2010       WindRiver Systems, Inc.
5efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
6efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * This program is free software; you can redistribute it and/or modify it
7efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * under the terms and conditions of the GNU General Public License,
8efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * version 2, as published by the Free Software Foundation.
9efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
10efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * This program is distributed in the hope it will be useful, but WITHOUT
11efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * more details.
14efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
15efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * You should have received a copy of the GNU General Public License along with
16efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * this program; if not, write to the Free Software Foundation, Inc.,
17efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
19efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * The full GNU General Public License is included in this distribution in
20efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the file called "COPYING".
21efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
22efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Author: Andreas Kies <andreas.kies@windriver.com>
23efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *		Vlad Lungu <vlad.lungu@windriver.com>
24efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
25efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
26efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
27efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/types.h>
28efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/kernel.h>
29efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/module.h>
30efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/init.h>
31efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/vmalloc.h>
32efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
33efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/videodev2.h>
34efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
35efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/kmod.h>
36efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
37efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/pci.h>
38efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/interrupt.h>
39efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/mutex.h>
40efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/io.h>
41efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/gpio.h>
42efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/i2c.h>
43efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <linux/delay.h>
44efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <media/v4l2-common.h>
45efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <media/v4l2-device.h>
46efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <media/v4l2-ioctl.h>
47efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include <media/videobuf-dma-contig.h>
48efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
49efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#include "sta2x11_vip.h"
50efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
51efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DRV_NAME "sta2x11_vip"
52efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DRV_VERSION "1.3"
53efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
54efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifndef PCI_DEVICE_ID_STMICRO_VIP
55efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define PCI_DEVICE_ID_STMICRO_VIP 0xCC0D
56efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif
57efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
58efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define MAX_FRAMES 4
59efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
60efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/*Register offsets*/
61efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_CTL		0x00
62efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_TFO		0x04
63efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_TFS		0x08
64efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_BFO		0x0C
65efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_BFS		0x10
66efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_VTP         0x14
67efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_VBP         0x18
68efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_VMP		0x1C
69efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_ITM		0x98
70efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_ITS		0x9C
71efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_STA		0xA0
72efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_HLFLN	0xA8
73efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_RGB		0xC0
74efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_PKZ		0xF0
75efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
76efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/*Register fields*/
77efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_CTL_ENA	0x00000001
78efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_CTL_RST	0x80000000
79efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_CTL_DIS	(~0x00040001)
80efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
81efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_IT_VSB	0x00000008
82efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_IT_VST	0x00000010
83efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_IT_FIFO	0x00000020
84efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
85efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define DVP_HLFLN_SD	0x00000001
86efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
87efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define REG_WRITE(vip, reg, value) iowrite32((value), (vip->iomem)+(reg))
88efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define REG_READ(vip, reg) ioread32((vip->iomem)+(reg))
89efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
90efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define SAVE_COUNT 8
91efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define AUX_COUNT 3
92efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#define IRQ_COUNT 1
93efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
94efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
95efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * struct sta2x11_vip - All internal data for one instance of device
96efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @v4l2_dev: device registered in v4l layer
97efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @video_dev: properties of our device
98efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device
99efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @adapter: contains I2C adapter information
100efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @register_save_area: All relevant register are saved here during suspend
101efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @decoder: contains information about video DAC
102efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @format: pixel format, fixed UYVY
103efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: video standard (e.g. PAL/NTSC)
104efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @input: input line for video signal ( 0 or 1 )
105efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @users: Number of open of device ( max. 1 )
106efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @disabled: Device is in power down state
107efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @mutex: ensures exclusive opening of device
108efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @slock: for excluse acces of registers
109efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vb_vidq: queue maintained by videobuf layer
110efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @capture: linked list of capture buffer
111efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @active: struct videobuf_buffer currently beingg filled
112efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @started: device is ready to capture frame
113efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @closing: device will be shut down
114efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @tcount: Number of top frames
115efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @bcount: Number of bottom frames
116efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @overflow: Number of FIFO overflows
117efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @mem_spare: small buffer of unused frame
118efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @dma_spare: dma addres of mem_spare
119efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @iomem: hardware base address
120efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @config: I2C and gpio config from platform
121efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
122efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * All non-local data is accessed via this structure.
123efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
124efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
125efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastruct sta2x11_vip {
126efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_device v4l2_dev;
127efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *video_dev;
128efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct pci_dev *pdev;
129efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct i2c_adapter *adapter;
130efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	unsigned int register_save_area[IRQ_COUNT + SAVE_COUNT + AUX_COUNT];
131efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_subdev *decoder;
132efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_pix_format format;
133efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	v4l2_std_id std;
134efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	unsigned int input;
135efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int users;
136efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int disabled;
137efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct mutex mutex;	/* exclusive access during open */
138efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spinlock_t slock;	/* spin lock for hardware and queue access */
139efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct videobuf_queue vb_vidq;
140efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct list_head capture;
141efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct videobuf_buffer *active;
142efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int started, closing, tcount, bcount;
143efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int overflow;
144efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	void *mem_spare;
145efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	dma_addr_t dma_spare;
146efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	void *iomem;
147efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct vip_config *config;
148efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
149efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
150efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic const unsigned int registers_to_save[AUX_COUNT] = {
151efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	DVP_HLFLN, DVP_RGB, DVP_PKZ
152efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
153efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
154efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct v4l2_pix_format formats_50[] = {
155efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*PAL interlaced */
156efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
157efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 576,
158efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
159efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_INTERLACED,
160efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
161efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 576,
162efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
163efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*PAL top */
164efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
165efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 288,
166efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
167efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_TOP,
168efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
169efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 288,
170efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
171efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*PAL bottom */
172efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
173efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 288,
174efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
175efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_BOTTOM,
176efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
177efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 288,
178efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
179efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
180efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
181efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
182efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct v4l2_pix_format formats_60[] = {
183efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*NTSC interlaced */
184efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
185efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 480,
186efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
187efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_INTERLACED,
188efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
189efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 480,
190efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
191efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*NTSC top */
192efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
193efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 240,
194efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
195efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_TOP,
196efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
197efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 240,
198efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
199efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{			/*NTSC bottom */
200efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .width = 720,
201efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .height = 240,
202efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .pixelformat = V4L2_PIX_FMT_UYVY,
203efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .field = V4L2_FIELD_BOTTOM,
204efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .bytesperline = 720 * 2,
205efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .sizeimage = 720 * 2 * 240,
206efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 .colorspace = V4L2_COLORSPACE_SMPTE170M},
207efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
208efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
209efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
210efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * buf_setup - Get size and number of video buffer
211efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vq: queue in videobuf
212efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @count: Number of buffers (1..MAX_FRAMES).
213efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *		0 use default value.
214efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @size:  size of buffer in bytes
215efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
216efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * returns size and number of buffers
217efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * a preset value of 0 returns the default number.
218efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, always succesfull.
219efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
220efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int buf_setup(struct videobuf_queue *vq, unsigned int *count,
221efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		     unsigned int *size)
222efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
223efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = vq->priv_data;
224efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
225efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	*size = vip->format.width * vip->format.height * 2;
226efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (0 == *count || MAX_FRAMES < *count)
227efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		*count = MAX_FRAMES;
228efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
229efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
230efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
231efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
232efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * buf_prepare - prepare buffer for usage
233efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vq: queue in videobuf layer
234efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vb: buffer to be prepared
235efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @field: type of video data (interlaced/non-interlaced)
236efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
237efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Allocate or realloc buffer
238efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, successful.
239efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
240efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EINVAL, supplied buffer is too small.
241efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
242efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *  other, buffer could not be locked.
243efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
244efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int buf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
245efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		       enum v4l2_field field)
246efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
247efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = vq->priv_data;
248efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret;
249efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
250efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vb->size = vip->format.width * vip->format.height * 2;
251efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if ((0 != vb->baddr) && (vb->bsize < vb->size))
252efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EINVAL;
253efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vb->width = vip->format.width;
254efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vb->height = vip->format.height;
255efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vb->field = field;
256efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
257efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (VIDEOBUF_NEEDS_INIT == vb->state) {
258efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = videobuf_iolock(vq, vb, NULL);
259efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (ret)
260efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			goto fail;
261efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
262efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vb->state = VIDEOBUF_PREPARED;
263efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
264efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagafail:
265efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	videobuf_dma_contig_free(vq, vb);
266efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vb->state = VIDEOBUF_NEEDS_INIT;
267efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return ret;
268efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
269efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
270efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
271efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * buf_queu - queue buffer for filling
272efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vq: queue in videobuf layer
273efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vb: buffer to be queued
274efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
275efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * if capturing is already running, the buffer will be queued. Otherwise
276efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * capture is started and the buffer is used directly.
277efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
278efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic void buf_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
279efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
280efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = vq->priv_data;
281efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	u32 dma;
282efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
283efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vb->state = VIDEOBUF_QUEUED;
284efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
285efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (vip->active) {
286efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		list_add_tail(&vb->queue, &vip->capture);
287efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return;
288efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
289efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
290efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->started = 1;
291efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->tcount = 0;
292efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->bcount = 0;
293efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->active = vb;
294efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vb->state = VIDEOBUF_ACTIVE;
295efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
296efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	dma = videobuf_to_dma_contig(vb);
297efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
298efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_TFO, (0 << 16) | (0));
299efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/* despite of interlace mode, upper and lower frames start at zero */
300efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_BFO, (0 << 16) | (0));
301efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
302efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	switch (vip->format.field) {
303efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_INTERLACED:
304efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_TFS,
305efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  ((vip->format.height / 2 - 1) << 16) |
306efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  (2 * vip->format.width - 1));
307efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_BFS, ((vip->format.height / 2 - 1) << 16) |
308efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  (2 * vip->format.width - 1));
309efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_VTP, dma);
310efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_VBP, dma + vip->format.width * 2);
311efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_VMP, 4 * vip->format.width);
312efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		break;
313efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_TOP:
314efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_TFS,
315efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  ((vip->format.height - 1) << 16) |
316efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  (2 * vip->format.width - 1));
317efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_BFS, ((0) << 16) |
318efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  (2 * vip->format.width - 1));
319efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_VTP, dma);
320efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_VBP, dma);
321efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_VMP, 2 * vip->format.width);
322efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		break;
323efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_BOTTOM:
324efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_TFS, ((0) << 16) |
325efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  (2 * vip->format.width - 1));
326efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_BFS,
327efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  ((vip->format.height) << 16) |
328efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  (2 * vip->format.width - 1));
329efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_VTP, dma);
330efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_VBP, dma);
331efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_VMP, 2 * vip->format.width);
332efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		break;
333efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
334efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	default:
335efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		pr_warning("VIP: unknown field format\n");
336efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return;
337efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
338efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
339efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_CTL, DVP_CTL_ENA);
340efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
341efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
342efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
343efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * buff_release - release buffer
344efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vq: queue in videobuf layer
345efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vb: buffer to be released
346efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
347efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * release buffer in videobuf layer
348efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
349efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic void buf_release(struct videobuf_queue *vq, struct videobuf_buffer *vb)
350efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
351efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
352efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	videobuf_dma_contig_free(vq, vb);
353efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vb->state = VIDEOBUF_NEEDS_INIT;
354efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
355efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
356efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct videobuf_queue_ops vip_qops = {
357efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.buf_setup = buf_setup,
358efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.buf_prepare = buf_prepare,
359efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.buf_queue = buf_queue,
360efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.buf_release = buf_release,
361efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
362efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
363efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
364efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_open - open video device
365efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device
366efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
367efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * open device, make sure it is only opened once.
368efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
369efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
370efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EBUSY, device is already opened
371efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
372efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -ENOMEM, no memory for auxiliary DMA buffer
373efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
374efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vip_open(struct file *file)
375efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
376efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = video_devdata(file);
377efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
378efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
379efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	mutex_lock(&vip->mutex);
380efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->users++;
381efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
382efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (vip->users > 1) {
383efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->users--;
384efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		mutex_unlock(&vip->mutex);
385efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EBUSY;
386efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
387efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
388efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	file->private_data = dev;
389efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->overflow = 0;
390efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->started = 0;
391efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->closing = 0;
392efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->active = NULL;
393efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
394efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	INIT_LIST_HEAD(&vip->capture);
395efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->mem_spare = dma_alloc_coherent(&vip->pdev->dev, 64,
396efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					    &vip->dma_spare, GFP_KERNEL);
397efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->mem_spare) {
398efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->users--;
399efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		mutex_unlock(&vip->mutex);
400efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -ENOMEM;
401efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
402efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
403efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	mutex_unlock(&vip->mutex);
404efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	videobuf_queue_dma_contig_init_cached(&vip->vb_vidq,
405efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					      &vip_qops,
406efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					      &vip->pdev->dev,
407efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					      &vip->slock,
408efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					      V4L2_BUF_TYPE_VIDEO_CAPTURE,
409efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					      V4L2_FIELD_INTERLACED,
410efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					      sizeof(struct videobuf_buffer),
411efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					      vip, NULL);
412efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_READ(vip, DVP_ITS);
413efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_HLFLN, DVP_HLFLN_SD);
414efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_ITM, DVP_IT_VSB | DVP_IT_VST);
415efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_CTL, DVP_CTL_RST);
416efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_CTL, 0);
417efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_READ(vip, DVP_ITS);
418efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
419efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
420efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
421efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
422efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_close - close video device
423efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device
424efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
425efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * close video device, wait until all pending operations are finished
426efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * ( maximum FRAME_MAX buffers pending )
427efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Turn off interrupts.
428efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
429efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, always succesful.
430efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
431efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vip_close(struct file *file)
432efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
433efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = video_devdata(file);
434efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
435efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
436efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->closing = 1;
437efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (vip->active)
438efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		videobuf_waiton(&vip->vb_vidq, vip->active, 0, 0);
439efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_lock_irq(&vip->slock);
440efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
441efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_ITM, 0);
442efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_CTL, DVP_CTL_RST);
443efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_CTL, 0);
444efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_READ(vip, DVP_ITS);
445efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
446efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->started = 0;
447efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->active = NULL;
448efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
449efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_unlock_irq(&vip->slock);
450efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
451efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	videobuf_stop(&vip->vb_vidq);
452efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	videobuf_mmap_free(&vip->vb_vidq);
453efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
454efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	dma_free_coherent(&vip->pdev->dev, 64, vip->mem_spare, vip->dma_spare);
455efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	file->private_data = NULL;
456efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	mutex_lock(&vip->mutex);
457efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->users--;
458efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	mutex_unlock(&vip->mutex);
459efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
460efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
461efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
462efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
463efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_read - read from video input
464efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device
465efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @data: user buffer
466efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @count: number of bytes to be read
467efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @ppos: position within stream
468efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
469efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * read video data from video device.
470efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * handling is done in generic videobuf layer
471efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: provided by videobuf layer
472efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
473efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic ssize_t vip_read(struct file *file, char __user *data,
474efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			size_t count, loff_t *ppos)
475efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
476efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = file->private_data;
477efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
478efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
479efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return videobuf_read_stream(&vip->vb_vidq, data, count, ppos, 0,
480efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				    file->f_flags & O_NONBLOCK);
481efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
482efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
483efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
484efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_mmap - map user buffer
485efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device
486efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vma: user buffer
487efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
488efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * map user space buffer into kernel mode, including DMA address.
489efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * handling is done in generic videobuf layer.
490efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: provided by videobuf layer
491efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
492efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vip_mmap(struct file *file, struct vm_area_struct *vma)
493efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
494efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = file->private_data;
495efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
496efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
497efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return videobuf_mmap_mapper(&vip->vb_vidq, vma);
498efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
499efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
500efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
501efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_poll - poll for event
502efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device
503efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @wait: contains events to be waited for
504efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
505efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * wait for event related to video device.
506efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * handling is done in generic videobuf layer.
507efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: provided by videobuf layer
508efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
509efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic unsigned int vip_poll(struct file *file, struct poll_table_struct *wait)
510efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
511efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = file->private_data;
512efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
513efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
514efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return videobuf_poll_stream(file, &vip->vb_vidq, wait);
515efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
516efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
517efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
518efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_querycap - return capabilities of device
519efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device (not used)
520efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
521efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @cap: contains return values
522efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
523efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the capabilities of the device are returned
524efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
525efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
526efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
527efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_querycap(struct file *file, void *priv,
528efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			   struct v4l2_capability *cap)
529efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
530efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
531efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
532efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
533efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	memset(cap, 0, sizeof(struct v4l2_capability));
534efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	strcpy(cap->driver, DRV_NAME);
535efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	strcpy(cap->card, DRV_NAME);
536efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	cap->version = 0;
537efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
538efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 pci_name(vip->pdev));
539efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
540efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	    V4L2_CAP_STREAMING;
541efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
542efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
543efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
544efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
545efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
546efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_s_std - set video standard
547efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device (not used)
548efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
549efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: contains standard to be set
550efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
551efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the video standard is set
552efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
553efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
554efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
555efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EIO, no input signal detected
556efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
557efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other, returned from video DAC.
558efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
559efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
560efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
561efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
562efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
563efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	v4l2_std_id oldstd = vip->std, newstd;
564efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int status;
565efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
566efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (V4L2_STD_ALL == *std) {
567efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		v4l2_subdev_call(vip->decoder, core, s_std, *std);
568efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ssleep(2);
569efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		v4l2_subdev_call(vip->decoder, video, querystd, &newstd);
570efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		v4l2_subdev_call(vip->decoder, video, g_input_status, &status);
571efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (status & V4L2_IN_ST_NO_SIGNAL)
572efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			return -EIO;
573efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		*std = vip->std = newstd;
574efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (oldstd != *std) {
5756ae009a8ba512d5b07386bbb1172cfd7a02986aaMauro Carvalho Chehab			if (V4L2_STD_525_60 & (*std))
576efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				vip->format = formats_60[0];
577efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			else
578efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				vip->format = formats_50[0];
579efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		}
580efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return 0;
581efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
582efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
583efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (oldstd != *std) {
5846ae009a8ba512d5b07386bbb1172cfd7a02986aaMauro Carvalho Chehab		if (V4L2_STD_525_60 & (*std))
585efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			vip->format = formats_60[0];
586efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		else
587efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			vip->format = formats_50[0];
588efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
589efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
590efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return v4l2_subdev_call(vip->decoder, core, s_std, *std);
591efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
592efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
593efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
594efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_g_std - get video standard
595efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device (not used)
596efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
597efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: contains return values
598efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
599efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the current video standard is returned
600efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
601efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
602efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
603efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
604efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
605efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
606efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
607efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
608efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	*std = vip->std;
609efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
610efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
611efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
612efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
613efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_querystd - get possible video standards
614efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device (not used)
615efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
616efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: contains return values
617efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
618efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * all possible video standards are returned
619efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
620efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: delivered by video DAC routine.
621efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
622efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
623efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
624efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
625efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
626efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
627efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return v4l2_subdev_call(vip->decoder, video, querystd, std);
628efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
629efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
630efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
631efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
632efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_queryctl - get possible control settings
633efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device (not used)
634efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
635efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @ctrl: contains return values
636efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
637efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return possible values for a control
638efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: delivered by video DAC routine.
639efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
640efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_queryctrl(struct file *file, void *priv,
641efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			    struct v4l2_queryctrl *ctrl)
642efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
643efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
644efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
645efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
646efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return v4l2_subdev_call(vip->decoder, core, queryctrl, ctrl);
647efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
648efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
649efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
650efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_g_ctl - get control value
651efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device (not used)
652efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
653efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @ctrl: contains return values
654efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
655efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return setting for a control value
656efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: delivered by video DAC routine.
657efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
658efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_g_ctrl(struct file *file, void *priv,
659efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			 struct v4l2_control *ctrl)
660efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
661efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
662efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
663efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
664efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return v4l2_subdev_call(vip->decoder, core, g_ctrl, ctrl);
665efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
666efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
667efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
668efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_s_ctl - set control value
669efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device (not used)
670efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
671efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @ctrl: contains value to be set
672efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
673efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * set value for a specific control
674efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: delivered by video DAC routine.
675efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
676efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_s_ctrl(struct file *file, void *priv,
677efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			 struct v4l2_control *ctrl)
678efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
679efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
680efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
681efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
682efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return v4l2_subdev_call(vip->decoder, core, s_ctrl, ctrl);
683efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
684efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
685efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
686efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_enum_input - return name of input line
687efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device (not used)
688efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
689efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @inp: contains return values
690efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
691efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the user friendly name of the input line is returned
692efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
693efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
694efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
695efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EINVAL, input line number out of range
696efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
697efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_enum_input(struct file *file, void *priv,
698efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			     struct v4l2_input *inp)
699efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
700efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (inp->index > 1)
701efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EINVAL;
702efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
703efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	inp->type = V4L2_INPUT_TYPE_CAMERA;
704efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	inp->std = V4L2_STD_ALL;
705efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	sprintf(inp->name, "Camera %u", inp->index);
706efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
707efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
708efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
709efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
710efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
711efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_s_input - set input line
712efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
713efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
714efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @i: new input line number
715efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
716efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the current active input line is set
717efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
718efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
719efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
720efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EINVAL, line number out of range
721efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
722efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_s_input(struct file *file, void *priv, unsigned int i)
723efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
724efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
725efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
726efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret;
727efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
728efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (i > 1)
729efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EINVAL;
730efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = v4l2_subdev_call(vip->decoder, video, s_routing, i, 0, 0);
731efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
732efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!ret)
733efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->input = i;
734efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
735efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
736efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
737efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
738efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
739efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_g_input - return input line
740efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
741efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
742efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @i: returned input line number
743efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
744efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the current active input line is returned
745efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
746efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: always 0.
747efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
748efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
749efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
750efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
751efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
752efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
753efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	*i = vip->input;
754efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
755efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
756efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
757efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
758efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_enum_fmt_vid_cap - return video capture format
759efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
760efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
761efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: returned format information
762efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
763efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * returns name and format of video capture
764efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Only UYVY is supported by hardware.
765efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
766efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: always 0.
767efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
768efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
769efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				   struct v4l2_fmtdesc *f)
770efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
771efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
772efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (f->index != 0)
773efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EINVAL;
774efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
775efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	strcpy(f->description, "4:2:2, packed, UYVY");
776efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->pixelformat = V4L2_PIX_FMT_UYVY;
777efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->flags = 0;
778efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
779efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
780efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
781efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
782efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_try_fmt_vid_cap - set video capture format
783efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
784efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
785efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: new format
786efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
787efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * new video format is set which includes width and
788efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * field type. width is fixed to 720, no scaling.
789efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Only UYVY is supported by this hardware.
790efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the minimum height is 200, the maximum is 576 (PAL)
791efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
792efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error
793efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
794efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EINVAL, pixel or field format not supported
795efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
796efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
797efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
798efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				  struct v4l2_format *f)
799efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
800efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
801efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
802efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int interlace_lim;
803efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
804efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (V4L2_PIX_FMT_UYVY != f->fmt.pix.pixelformat)
805efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EINVAL;
806efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
8076ae009a8ba512d5b07386bbb1172cfd7a02986aaMauro Carvalho Chehab	if (V4L2_STD_525_60 & vip->std)
808efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		interlace_lim = 240;
809efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	else
810efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		interlace_lim = 288;
811efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
812efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	switch (f->fmt.pix.field) {
813efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_ANY:
814efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (interlace_lim < f->fmt.pix.height)
815efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			f->fmt.pix.field = V4L2_FIELD_INTERLACED;
816efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		else
817efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			f->fmt.pix.field = V4L2_FIELD_BOTTOM;
818efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		break;
819efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_TOP:
820efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_BOTTOM:
821efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (interlace_lim < f->fmt.pix.height)
822efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			f->fmt.pix.height = interlace_lim;
823efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		break;
824efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	case V4L2_FIELD_INTERLACED:
825efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		break;
826efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	default:
827efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return -EINVAL;
828efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
829efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
830efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.height &= ~1;
831efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (2 * interlace_lim < f->fmt.pix.height)
832efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		f->fmt.pix.height = 2 * interlace_lim;
833efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (200 > f->fmt.pix.height)
834efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		f->fmt.pix.height = 200;
835efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.width = 720;
836efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
837efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.sizeimage = f->fmt.pix.width * 2 * f->fmt.pix.height;
838efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
839efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	f->fmt.pix.priv = 0;
840efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
841efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
842efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
843efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
844efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_s_fmt_vid_cap - set current video format parameters
845efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
846efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
847efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: returned format information
848efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
849efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * set new capture format
850efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error
851efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
852efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other, delivered by video DAC routine.
853efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
854efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
855efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				struct v4l2_format *f)
856efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
857efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
858efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
859efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret;
860efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
861efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = vidioc_try_fmt_vid_cap(file, priv, f);
862efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret)
863efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
864efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
865efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	memcpy(&vip->format, &f->fmt.pix, sizeof(struct v4l2_pix_format));
866efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
867efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
868efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
869efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
870efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_g_fmt_vid_cap - get current video format parameters
871efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
872efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
873efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: contains format information
874efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
875efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * returns current video format parameters
876efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
877efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, always successful
878efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
879efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
880efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				struct v4l2_format *f)
881efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
882efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
883efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
884efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
885efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	memcpy(&f->fmt.pix, &vip->format, sizeof(struct v4l2_pix_format));
886efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
887efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
888efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
889efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
890efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_reqfs - request buffer
891efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
892efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
893efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @p: video buffer
894efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
895efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Handling is done in generic videobuf layer.
896efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
897efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_reqbufs(struct file *file, void *priv,
898efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  struct v4l2_requestbuffers *p)
899efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
900efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
901efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
902efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
903efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return videobuf_reqbufs(&vip->vb_vidq, p);
904efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
905efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
906efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
907efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_querybuf - query buffer
908efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
909efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
910efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @p: video buffer
911efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
912efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * query buffer state.
913efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Handling is done in generic videobuf layer.
914efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
915efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
916efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
917efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
918efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
919efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
920efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return videobuf_querybuf(&vip->vb_vidq, p);
921efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
922efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
923efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
924efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_qbuf - queue a buffer
925efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
926efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
927efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @p: video buffer
928efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
929efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Handling is done in generic videobuf layer.
930efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
931efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
932efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
933efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
934efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
935efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
936efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return videobuf_qbuf(&vip->vb_vidq, p);
937efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
938efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
939efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
940efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_dqbuf - dequeue a buffer
941efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
942efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
943efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @p: video buffer
944efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
945efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Handling is done in generic videobuf layer.
946efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
947efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
948efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
949efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
950efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
951efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
952efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return videobuf_dqbuf(&vip->vb_vidq, p, file->f_flags & O_NONBLOCK);
953efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
954efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
955efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
956efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_streamon - turn on streaming
957efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
958efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
959efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @type: type of capture
960efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
961efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * turn on streaming.
962efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Handling is done in generic videobuf layer.
963efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
964efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_streamon(struct file *file, void *priv,
965efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			   enum v4l2_buf_type type)
966efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
967efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
968efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
969efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
970efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return videobuf_streamon(&vip->vb_vidq);
971efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
972efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
973efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
974efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_streamoff - turn off streaming
975efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @file: descriptor of device ( not used)
976efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @priv: points to current videodevice
977efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @type: type of capture
978efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
979efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * turn off streaming.
980efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Handling is done in generic videobuf layer.
981efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
982efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_streamoff(struct file *file, void *priv,
983efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			    enum v4l2_buf_type type)
984efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
985efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct video_device *dev = priv;
986efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip = video_get_drvdata(dev);
987efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
988efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return videobuf_streamoff(&vip->vb_vidq);
989efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
990efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
991efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic const struct v4l2_file_operations vip_fops = {
992efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.owner = THIS_MODULE,
993efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.open = vip_open,
994efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.release = vip_close,
995efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.ioctl = video_ioctl2,
996efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.read = vip_read,
997efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.mmap = vip_mmap,
998efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.poll = vip_poll
999efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
1000efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1001efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic const struct v4l2_ioctl_ops vip_ioctl_ops = {
1002efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_querycap = vidioc_querycap,
1003efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_s_std = vidioc_s_std,
1004efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_g_std = vidioc_g_std,
1005efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_querystd = vidioc_querystd,
1006efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_queryctrl = vidioc_queryctrl,
1007efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_g_ctrl = vidioc_g_ctrl,
1008efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_s_ctrl = vidioc_s_ctrl,
1009efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_enum_input = vidioc_enum_input,
1010efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1011efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_s_input = vidioc_s_input,
1012efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_g_input = vidioc_g_input,
1013efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1014efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1015efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1016efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_reqbufs = vidioc_reqbufs,
1017efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_querybuf = vidioc_querybuf,
1018efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_qbuf = vidioc_qbuf,
1019efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_dqbuf = vidioc_dqbuf,
1020efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_streamon = vidioc_streamon,
1021efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.vidioc_streamoff = vidioc_streamoff,
1022efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
1023efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1024efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct video_device video_dev_template = {
1025efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.name = DRV_NAME,
1026efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.release = video_device_release,
1027efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.fops = &vip_fops,
1028efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.ioctl_ops = &vip_ioctl_ops,
1029efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.tvnorms = V4L2_STD_ALL,
1030efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
1031efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1032efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
1033efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_irq - interrupt routine
1034efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @irq: Number of interrupt ( not used, correct number is assumed )
1035efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vip: local data structure containing all information
1036efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1037efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * check for both frame interrupts set ( top and bottom ).
1038efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * check FIFO overflow, but limit number of log messages after open.
1039efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * signal a complete buffer if done.
1040efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * dequeue a new buffer if available.
1041efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * disable VIP if no buffer available.
1042efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1043efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: IRQ_NONE, interrupt was not generated by VIP
1044efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1045efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * IRQ_HANDLED, interrupt done.
1046efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
1047efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
1048efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1049efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	u32 status, dma;
1050efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	unsigned long flags;
1051efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct videobuf_buffer *vb;
1052efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1053efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	status = REG_READ(vip, DVP_ITS);
1054efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1055efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!status) {
1056efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		pr_debug("VIP: irq ignored\n");
1057efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return IRQ_NONE;
1058efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1059efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1060efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->started)
1061efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return IRQ_HANDLED;
1062efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1063efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (status & DVP_IT_VSB)
1064efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->bcount++;
1065efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1066efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (status & DVP_IT_VST)
1067efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->tcount++;
1068efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1069efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if ((DVP_IT_VSB | DVP_IT_VST) == (status & (DVP_IT_VST | DVP_IT_VSB))) {
1070efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		/* this is bad, we are too slow, hope the condition is gone
1071efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 * on the next frame */
1072efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		pr_info("VIP: both irqs\n");
1073efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return IRQ_HANDLED;
1074efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1075efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1076efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (status & DVP_IT_FIFO) {
1077efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (5 > vip->overflow++)
1078efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			pr_info("VIP: fifo overflow\n");
1079efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1080efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1081efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (2 > vip->tcount)
1082efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return IRQ_HANDLED;
1083efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1084efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (status & DVP_IT_VSB)
1085efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return IRQ_HANDLED;
1086efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1087efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_lock_irqsave(&vip->slock, flags);
1088efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1089efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_CTL, REG_READ(vip, DVP_CTL) & ~DVP_CTL_ENA);
1090efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (vip->active) {
1091efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		do_gettimeofday(&vip->active->ts);
1092efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->active->field_count++;
1093efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->active->state = VIDEOBUF_DONE;
1094efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		wake_up(&vip->active->done);
1095efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->active = NULL;
1096efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1097efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->closing) {
1098efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (list_empty(&vip->capture))
1099efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			goto done;
1100efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1101efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vb = list_first_entry(&vip->capture, struct videobuf_buffer,
1102efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				      queue);
1103efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (NULL == vb) {
1104efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			pr_info("VIP: no buffer\n");
1105efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			goto done;
1106efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		}
1107efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vb->state = VIDEOBUF_ACTIVE;
1108efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		list_del(&vb->queue);
1109efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->active = vb;
1110efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dma = videobuf_to_dma_contig(vb);
1111efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		switch (vip->format.field) {
1112efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		case V4L2_FIELD_INTERLACED:
1113efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			REG_WRITE(vip, DVP_VTP, dma);
1114efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			REG_WRITE(vip, DVP_VBP, dma + vip->format.width * 2);
1115efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			break;
1116efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		case V4L2_FIELD_TOP:
1117efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		case V4L2_FIELD_BOTTOM:
1118efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			REG_WRITE(vip, DVP_VTP, dma);
1119efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			REG_WRITE(vip, DVP_VBP, dma);
1120efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			break;
1121efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		default:
1122efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			pr_warning("VIP: unknown field format\n");
1123efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			goto done;
1124efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			break;
1125efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		}
1126efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, DVP_CTL, REG_READ(vip, DVP_CTL) | DVP_CTL_ENA);
1127efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1128efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagadone:
1129efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_unlock_irqrestore(&vip->slock, flags);
1130efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return IRQ_HANDLED;
1131efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1132efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1133efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
1134efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_gpio_reserve - reserve gpio pin
1135efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @dev: device
1136efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pin: GPIO pin number
1137efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @dir: direction, input or output
1138efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @name: GPIO pin name
1139efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1140efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
1141efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vip_gpio_reserve(struct device *dev, int pin, int dir,
1142efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			    const char *name)
1143efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1144efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret;
1145efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1146efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (pin == -1)
1147efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return 0;
1148efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1149efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = gpio_request(pin, name);
1150efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret) {
1151efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(dev, "Failed to allocate pin %d (%s)\n", pin, name);
1152efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
1153efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1154efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1155efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = gpio_direction_output(pin, dir);
1156efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret) {
1157efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(dev, "Failed to set direction for pin %d (%s)\n",
1158efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			pin, name);
1159efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		gpio_free(pin);
1160efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
1161efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1162efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1163efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = gpio_export(pin, false);
1164efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret) {
1165efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(dev, "Failed to export pin %d (%s)\n", pin, name);
1166efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		gpio_free(pin);
1167efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
1168efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1169efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1170efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
1171efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1172efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1173efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
1174efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_gpio_release - release gpio pin
1175efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @dev: device
1176efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pin: GPIO pin number
1177efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @name: GPIO pin name
1178efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1179efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
1180efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic void vip_gpio_release(struct device *dev, int pin, const char *name)
1181efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1182efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (pin != -1) {
1183efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_dbg(dev, "releasing pin %d (%s)\n",	pin, name);
1184efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		gpio_unexport(pin);
1185efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		gpio_free(pin);
1186efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1187efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1188efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1189efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
1190efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_init_one - init one instance of video device
1191efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device
1192efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @ent: (not used)
1193efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1194efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * allocate reset pins for DAC.
1195efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Reset video DAC, this is done via reset line.
1196efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * allocate memory for managing device
1197efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * request interrupt
1198efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * map IO region
1199efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * register device
1200efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * find and initialize video DAC
1201efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1202efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error
1203efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1204efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -ENOMEM, no memory
1205efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1206efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -ENODEV, device could not be detected or registered
1207efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
1208efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int __devinit sta2x11_vip_init_one(struct pci_dev *pdev,
1209efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					  const struct pci_device_id *ent)
1210efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1211efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret;
1212efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip;
1213efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct vip_config *config;
1214efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1215efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = pci_enable_device(pdev);
1216efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret)
1217efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
1218efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1219efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	config = dev_get_platdata(&pdev->dev);
1220efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!config) {
1221efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_info(&pdev->dev, "VIP slot disabled\n");
1222efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -EINVAL;
1223efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto disable;
1224efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1225efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1226efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = vip_gpio_reserve(&pdev->dev, config->pwr_pin, 0,
1227efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			       config->pwr_name);
1228efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret)
1229efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto disable;
1230efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1231efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (config->reset_pin >= 0) {
1232efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = vip_gpio_reserve(&pdev->dev, config->reset_pin, 0,
1233efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga				       config->reset_name);
1234efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (ret) {
1235efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			vip_gpio_release(&pdev->dev, config->pwr_pin,
1236efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					 config->pwr_name);
1237efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			goto disable;
1238efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		}
1239efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1240efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1241efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (config->pwr_pin != -1) {
1242efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		/* Datasheet says 5ms between PWR and RST */
1243efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		usleep_range(5000, 25000);
1244efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = gpio_direction_output(config->pwr_pin, 1);
1245efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1246efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1247efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (config->reset_pin != -1) {
1248efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		/* Datasheet says 5ms between PWR and RST */
1249efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		usleep_range(5000, 25000);
1250efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = gpio_direction_output(config->reset_pin, 1);
1251efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1252efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	usleep_range(5000, 25000);
1253efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1254efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip = kzalloc(sizeof(struct sta2x11_vip), GFP_KERNEL);
1255efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip) {
1256efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENOMEM;
1257efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto release_gpios;
1258efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1259efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1260efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->pdev = pdev;
1261efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->std = V4L2_STD_PAL;
1262efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->format = formats_50[0];
1263efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->config = config;
1264efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1265efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (v4l2_device_register(&pdev->dev, &vip->v4l2_dev))
1266efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto free_mem;
1267efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1268efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	dev_dbg(&pdev->dev, "BAR #0 at 0x%lx 0x%lx irq %d\n",
1269efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		(unsigned long)pci_resource_start(pdev, 0),
1270efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		(unsigned long)pci_resource_len(pdev, 0), pdev->irq);
1271efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1272efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_set_master(pdev);
1273efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1274efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = pci_request_regions(pdev, DRV_NAME);
1275efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret)
1276efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto unreg;
1277efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1278efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->iomem = pci_iomap(pdev, 0, 0x100);
1279efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->iomem) {
1280efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENOMEM; /* FIXME */
1281efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto release;
1282efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1283efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1284efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_enable_msi(pdev);
1285efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1286efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	INIT_LIST_HEAD(&vip->capture);
1287efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_lock_init(&vip->slock);
1288efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	mutex_init(&vip->mutex);
1289efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->started = 0;
1290efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->disabled = 0;
1291efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1292efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = request_irq(pdev->irq,
1293efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  (irq_handler_t) vip_irq,
1294efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  IRQF_SHARED, DRV_NAME, vip);
1295efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret) {
1296efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(&pdev->dev, "request_irq failed\n");
1297efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENODEV;
1298efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto unmap;
1299efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1300efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1301efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->video_dev = video_device_alloc();
1302efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->video_dev) {
1303efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENOMEM;
1304efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto release_irq;
1305efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1306efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1307efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	*(vip->video_dev) = video_dev_template;
1308efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	video_set_drvdata(vip->video_dev, vip);
1309efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1310efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = video_register_device(vip->video_dev, VFL_TYPE_GRABBER, -1);
1311efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret)
1312efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto vrelease;
1313efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1314efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->adapter = i2c_get_adapter(vip->config->i2c_id);
1315efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->adapter) {
1316efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENODEV;
1317efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(&pdev->dev, "no I2C adapter found\n");
1318efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto vunreg;
1319efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1320efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1321efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->decoder = v4l2_i2c_new_subdev(&vip->v4l2_dev, vip->adapter,
1322efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					   "adv7180", vip->config->i2c_addr,
1323efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga					   NULL);
1324efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (!vip->decoder) {
1325efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = -ENODEV;
1326efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		dev_err(&pdev->dev, "no decoder found\n");
1327efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		goto vunreg;
1328efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1329efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1330efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	i2c_put_adapter(vip->adapter);
1331efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1332efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	v4l2_subdev_call(vip->decoder, core, init, 0);
1333efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1334efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pr_info("STA2X11 Video Input Port (VIP) loaded\n");
1335efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
1336efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1337efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagavunreg:
1338efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	video_set_drvdata(vip->video_dev, NULL);
1339efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagavrelease:
1340efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (video_is_registered(vip->video_dev))
1341efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		video_unregister_device(vip->video_dev);
1342efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	else
1343efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		video_device_release(vip->video_dev);
1344efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagarelease_irq:
1345efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	free_irq(pdev->irq, vip);
1346efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_disable_msi(pdev);
1347efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagaunmap:
1348efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_iounmap(pdev, vip->iomem);
1349efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	mutex_destroy(&vip->mutex);
1350efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagarelease:
1351efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_release_regions(pdev);
1352efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagaunreg:
1353efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	v4l2_device_unregister(&vip->v4l2_dev);
1354efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagafree_mem:
1355efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	kfree(vip);
1356efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagarelease_gpios:
1357efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip_gpio_release(&pdev->dev, config->reset_pin, config->reset_name);
1358efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip_gpio_release(&pdev->dev, config->pwr_pin, config->pwr_name);
1359efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagadisable:
1360efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/*
1361efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 * do not call pci_disable_device on sta2x11 because it break all
1362efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 * other Bus masters on this EP
1363efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 */
1364efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return ret;
1365efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1366efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1367efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
1368efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_remove_one - release device
1369efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device
1370efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1371efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Undo everything done in .._init_one
1372efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1373efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * unregister video device
1374efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * free interrupt
1375efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * unmap ioadresses
1376efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * free memory
1377efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * free GPIO pins
1378efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
1379efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic void __devexit sta2x11_vip_remove_one(struct pci_dev *pdev)
1380efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1381efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
1382efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip =
1383efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	    container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1384efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1385efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	video_set_drvdata(vip->video_dev, NULL);
1386efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	video_unregister_device(vip->video_dev);
1387efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/*do not call video_device_release() here, is already done */
1388efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	free_irq(pdev->irq, vip);
1389efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_disable_msi(pdev);
1390efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_iounmap(pdev, vip->iomem);
1391efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_release_regions(pdev);
1392efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1393efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	v4l2_device_unregister(&vip->v4l2_dev);
1394efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	mutex_destroy(&vip->mutex);
1395efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1396efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip_gpio_release(&pdev->dev, vip->config->pwr_pin,
1397efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			 vip->config->pwr_name);
1398efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip_gpio_release(&pdev->dev, vip->config->reset_pin,
1399efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			 vip->config->reset_name);
1400efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1401efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	kfree(vip);
1402efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/*
1403efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 * do not call pci_disable_device on sta2x11 because it break all
1404efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 * other Bus masters on this EP
1405efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	 */
1406efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1407efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1408efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifdef CONFIG_PM
1409efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1410efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
1411efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_suspend - set device into power save mode
1412efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device
1413efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @state: new state of device
1414efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1415efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * all relevant registers are saved and an attempt to set a new state is made.
1416efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1417efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0 always indicate success,
1418efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * even if device could not be disabled. (workaround for hardware problem)
1419efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1420efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * reurn value : 0, always succesful, even if hardware does not not support
1421efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * power down mode.
1422efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
1423efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int sta2x11_vip_suspend(struct pci_dev *pdev, pm_message_t state)
1424efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1425efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
1426efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip =
1427efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	    container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1428efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	unsigned long flags;
1429efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int i;
1430efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1431efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_lock_irqsave(&vip->slock, flags);
1432efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->register_save_area[0] = REG_READ(vip, DVP_CTL);
1433efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_CTL, vip->register_save_area[0] & DVP_CTL_DIS);
1434efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	vip->register_save_area[SAVE_COUNT] = REG_READ(vip, DVP_ITM);
1435efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_ITM, 0);
1436efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	for (i = 1; i < SAVE_COUNT; i++)
1437efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->register_save_area[i] = REG_READ(vip, 4 * i);
1438efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	for (i = 0; i < AUX_COUNT; i++)
1439efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i] =
1440efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		    REG_READ(vip, registers_to_save[i]);
1441efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_unlock_irqrestore(&vip->slock, flags);
1442efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/* save pci state */
1443efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_save_state(pdev);
1444efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (pci_set_power_state(pdev, pci_choose_state(pdev, state))) {
1445efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		/*
1446efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 * do not call pci_disable_device on sta2x11 because it
1447efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 * break all other Bus masters on this EP
1448efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 */
1449efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->disabled = 1;
1450efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1451efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1452efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pr_info("VIP: suspend\n");
1453efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
1454efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1455efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1456efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/**
1457efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_resume - resume device operation
1458efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev : PCI device
1459efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1460efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * re-enable device, set PCI state to powered and restore registers.
1461efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * resume normal device operation afterwards.
1462efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1463efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error.
1464efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *
1465efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other, could not set device to power on state.
1466efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */
1467efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int sta2x11_vip_resume(struct pci_dev *pdev)
1468efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1469efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
1470efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	struct sta2x11_vip *vip =
1471efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	    container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1472efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	unsigned long flags;
1473efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	int ret, i;
1474efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1475efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pr_info("VIP: resume\n");
1476efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	/* restore pci state */
1477efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (vip->disabled) {
1478efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		ret = pci_enable_device(pdev);
1479efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		if (ret) {
1480efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			pr_warning("VIP: Can't enable device.\n");
1481efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			return ret;
1482efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		}
1483efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->disabled = 0;
1484efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1485efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	ret = pci_set_power_state(pdev, PCI_D0);
1486efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	if (ret) {
1487efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		/*
1488efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 * do not call pci_disable_device on sta2x11 because it
1489efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 * break all other Bus masters on this EP
1490efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		 */
1491efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		pr_warning("VIP: Can't enable device.\n");
1492efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		vip->disabled = 1;
1493efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		return ret;
1494efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	}
1495efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1496efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_restore_state(pdev);
1497efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1498efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_lock_irqsave(&vip->slock, flags);
1499efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	for (i = 1; i < SAVE_COUNT; i++)
1500efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, 4 * i, vip->register_save_area[i]);
1501efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	for (i = 0; i < AUX_COUNT; i++)
1502efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga		REG_WRITE(vip, registers_to_save[i],
1503efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga			  vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i]);
1504efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_CTL, vip->register_save_area[0]);
1505efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	REG_WRITE(vip, DVP_ITM, vip->register_save_area[SAVE_COUNT]);
1506efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	spin_unlock_irqrestore(&vip->slock, flags);
1507efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return 0;
1508efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1509efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1510efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif
1511efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1512efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic DEFINE_PCI_DEVICE_TABLE(sta2x11_vip_pci_tbl) = {
1513efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIP)},
1514efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	{0,}
1515efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
1516efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1517efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct pci_driver sta2x11_vip_driver = {
1518efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.name = DRV_NAME,
1519efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.probe = sta2x11_vip_init_one,
1520efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.remove = __devexit_p(sta2x11_vip_remove_one),
1521efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.id_table = sta2x11_vip_pci_tbl,
1522efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifdef CONFIG_PM
1523efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.suspend = sta2x11_vip_suspend,
1524efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	.resume = sta2x11_vip_resume,
1525efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif
1526efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga};
1527efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1528efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int __init sta2x11_vip_init_module(void)
1529efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1530efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	return pci_register_driver(&sta2x11_vip_driver);
1531efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1532efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1533efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic void __exit sta2x11_vip_exit_module(void)
1534efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{
1535efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga	pci_unregister_driver(&sta2x11_vip_driver);
1536efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}
1537efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1538efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifdef MODULE
1539efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagamodule_init(sta2x11_vip_init_module);
1540efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagamodule_exit(sta2x11_vip_exit_module);
1541efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#else
1542efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagalate_initcall_sync(sta2x11_vip_init_module);
1543efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif
1544efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga
1545efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_DESCRIPTION("STA2X11 Video Input Port driver");
1546efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_AUTHOR("Wind River");
1547efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_LICENSE("GPL v2");
1548efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_SUPPORTED_DEVICE("sta2x11 video input");
1549efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_VERSION(DRV_VERSION);
1550efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_DEVICE_TABLE(pci, sta2x11_vip_pci_tbl);
1551