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