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