sta2x11_vip.c revision d017650b40b4cb5c4158e3b9af38af164986b022
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 1558dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga void *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} 3308dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int 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 3408dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip_active_buf_next(vip); 341efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 342efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 343efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 344efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 3458dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int start_streaming(struct vb2_queue *vq, unsigned int count) 346efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 3478dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = vb2_get_drv_priv(vq); 348efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 349efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga spin_lock_irq(&vip->slock); 3508dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Enable interrupt VSYNC Top and Bottom*/ 3518dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_ITM, DVP_IT_VSB | DVP_IT_VST); 352efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga spin_unlock_irq(&vip->slock); 353efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 3548dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (count) 3558dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga start_dma(vip, vip->active); 356efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 357efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 358efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 359efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 3608dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga/* abort streaming and wait for last buffer */ 3618dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int stop_streaming(struct vb2_queue *vq) 362efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 3638dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = vb2_get_drv_priv(vq); 3648dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct vip_buffer *vip_buf, *node; 3658dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 3668dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Disable acquisition */ 3678dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_CTL, reg_read(vip, DVP_CTL) & ~DVP_CTL_ENA); 3688dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Disable all interrupts */ 3698dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_ITM, 0); 3708dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 3718dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Release all active buffers */ 3728dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga spin_lock(&vip->lock); 3738dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga list_for_each_entry_safe(vip_buf, node, &vip->buffer_list, list) { 3748dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vb2_buffer_done(&vip_buf->vb, VB2_BUF_STATE_ERROR); 3758dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga list_del(&vip_buf->list); 3768dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga } 3778dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga spin_unlock(&vip->lock); 3788dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return 0; 379efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 380efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 3818dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic struct vb2_ops vip_video_qops = { 3828dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .queue_setup = queue_setup, 3838dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .buf_init = buffer_init, 3848dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .buf_prepare = buffer_prepare, 3858dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .buf_finish = buffer_finish, 3868dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .buf_queue = buffer_queue, 3878dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .start_streaming = start_streaming, 3888dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .stop_streaming = stop_streaming, 3898dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}; 390efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 391efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 3928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga/* File Operations */ 3938dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic const struct v4l2_file_operations vip_fops = { 3948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .owner = THIS_MODULE, 3958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .open = v4l2_fh_open, 3968dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .release = vb2_fop_release, 3978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .unlocked_ioctl = video_ioctl2, 3988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .read = vb2_fop_read, 3998dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .mmap = vb2_fop_mmap, 4008dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .poll = vb2_fop_poll 4018dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga}; 402efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 403efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 404efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 405efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_querycap - return capabilities of device 4068dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device 407efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @cap: contains return values 408efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 409efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the capabilities of the device are returned 410efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 411efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error. 412efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 413efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_querycap(struct file *file, void *priv, 414efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct v4l2_capability *cap) 415efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 4168dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = video_drvdata(file); 417efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 4188dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga strcpy(cap->driver, KBUILD_MODNAME); 4198dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga strcpy(cap->card, KBUILD_MODNAME); 420efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", 421efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_name(vip->pdev)); 4228dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | 4238dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga V4L2_CAP_STREAMING; 4248dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; 425efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 426efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 427efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 428efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 429efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 430efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_s_std - set video standard 4318dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device 432efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: contains standard to be set 433efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 434efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the video standard is set 435efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 436efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error. 437efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 438efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EIO, no input signal detected 439efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 440efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other, returned from video DAC. 441efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 442314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuilstatic int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std) 443efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 4448dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = video_drvdata(file); 445efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga v4l2_std_id oldstd = vip->std, newstd; 446efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga int status; 447efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 448314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil if (V4L2_STD_ALL == std) { 449314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil v4l2_subdev_call(vip->decoder, core, s_std, std); 450efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ssleep(2); 451efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga v4l2_subdev_call(vip->decoder, video, querystd, &newstd); 452efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga v4l2_subdev_call(vip->decoder, video, g_input_status, &status); 453efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (status & V4L2_IN_ST_NO_SIGNAL) 454efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return -EIO; 455314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil std = vip->std = newstd; 456314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil if (oldstd != std) { 457314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil if (V4L2_STD_525_60 & std) 458efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->format = formats_60[0]; 459efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga else 460efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->format = formats_50[0]; 461efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 462efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 463efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 464efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 465314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil if (oldstd != std) { 466314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil if (V4L2_STD_525_60 & std) 467efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->format = formats_60[0]; 468efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga else 469efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->format = formats_50[0]; 470efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 471efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 472314527acbbb3f33f72c2ef19d8cfabcada9912a5Hans Verkuil return v4l2_subdev_call(vip->decoder, core, s_std, std); 473efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 474efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 475efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 476efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_g_std - get video standard 4778dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device 478efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: contains return values 479efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 480efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the current video standard is returned 481efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 482efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error. 483efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 484efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std) 485efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 4868dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = video_drvdata(file); 487efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 488efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *std = vip->std; 489efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 490efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 491efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 492efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 493efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_querystd - get possible video standards 4948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device 495efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @std: contains return values 496efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 497efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * all possible video standards are returned 498efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 499efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: delivered by video DAC routine. 500efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 501efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std) 502efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 5038dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = video_drvdata(file); 504efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 505efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return v4l2_subdev_call(vip->decoder, video, querystd, std); 506efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 507efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 508efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_enum_input(struct file *file, void *priv, 509efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct v4l2_input *inp) 510efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 511efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (inp->index > 1) 512efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return -EINVAL; 513efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 514efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga inp->type = V4L2_INPUT_TYPE_CAMERA; 515efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga inp->std = V4L2_STD_ALL; 516efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga sprintf(inp->name, "Camera %u", inp->index); 517efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 518efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 519efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 520efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 521efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 522efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_s_input - set input line 5238dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device 524efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @i: new input line number 525efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 526efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the current active input line is set 527efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 528efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error. 529efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 530efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EINVAL, line number out of range 531efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 532efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_s_input(struct file *file, void *priv, unsigned int i) 533efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 5348dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = video_drvdata(file); 535efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga int ret; 536efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 537efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (i > 1) 538efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return -EINVAL; 539efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = v4l2_subdev_call(vip->decoder, video, s_routing, i, 0, 0); 540efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 541efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (!ret) 542efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->input = i; 543efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 544efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 545efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 546efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 547efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 548efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_g_input - return input line 5498dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device 550efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @i: returned input line number 551efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 552efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the current active input line is returned 553efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 554efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: always 0. 555efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 556efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_g_input(struct file *file, void *priv, unsigned int *i) 557efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 5588dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = video_drvdata(file); 559efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 560efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga *i = vip->input; 561efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 562efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 563efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 564efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 565efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_enum_fmt_vid_cap - return video capture format 566efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: returned format information 567efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 568efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * returns name and format of video capture 569efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Only UYVY is supported by hardware. 570efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 571efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: always 0. 572efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 573efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 574efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct v4l2_fmtdesc *f) 575efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 576efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 577efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (f->index != 0) 578efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return -EINVAL; 579efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 580efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga strcpy(f->description, "4:2:2, packed, UYVY"); 581efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->pixelformat = V4L2_PIX_FMT_UYVY; 582efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->flags = 0; 583efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 584efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 585efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 586efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 587efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_try_fmt_vid_cap - set video capture format 5888dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device 589efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: new format 590efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 591efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * new video format is set which includes width and 592efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * field type. width is fixed to 720, no scaling. 593efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Only UYVY is supported by this hardware. 594efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * the minimum height is 200, the maximum is 576 (PAL) 595efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 596efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error 597efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 598efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -EINVAL, pixel or field format not supported 599efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 600efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 601efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 602efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct v4l2_format *f) 603efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 6048dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = video_drvdata(file); 605efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga int interlace_lim; 606efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 6078dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (V4L2_PIX_FMT_UYVY != f->fmt.pix.pixelformat) { 6088dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga v4l2_warn(&vip->v4l2_dev, "Invalid format, only UYVY supported\n"); 609efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return -EINVAL; 6108dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga } 611efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 6126ae009a8ba512d5b07386bbb1172cfd7a02986aaMauro Carvalho Chehab if (V4L2_STD_525_60 & vip->std) 613efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga interlace_lim = 240; 614efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga else 615efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga interlace_lim = 288; 616efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 617efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga switch (f->fmt.pix.field) { 6188dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga default: 619efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga case V4L2_FIELD_ANY: 620efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (interlace_lim < f->fmt.pix.height) 621efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.field = V4L2_FIELD_INTERLACED; 622efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga else 623efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.field = V4L2_FIELD_BOTTOM; 624efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga break; 625efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga case V4L2_FIELD_TOP: 626efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga case V4L2_FIELD_BOTTOM: 627efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (interlace_lim < f->fmt.pix.height) 628efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.height = interlace_lim; 629efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga break; 630efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga case V4L2_FIELD_INTERLACED: 631efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga break; 632efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 633efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 6348dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* It is the only supported format */ 6358dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; 636efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.height &= ~1; 637efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (2 * interlace_lim < f->fmt.pix.height) 638efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.height = 2 * interlace_lim; 639efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (200 > f->fmt.pix.height) 640efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.height = 200; 641efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.width = 720; 642efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 643efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.sizeimage = f->fmt.pix.width * 2 * f->fmt.pix.height; 644efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 645efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga f->fmt.pix.priv = 0; 646efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 647efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 648efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 649efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 650efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_s_fmt_vid_cap - set current video format parameters 6518dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device 652efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: returned format information 653efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 654efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * set new capture format 655efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error 656efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 657efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other, delivered by video DAC routine. 658efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 659efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 660efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct v4l2_format *f) 661efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 6628dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = video_drvdata(file); 6638dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga unsigned int t_stop, b_stop, pitch; 664efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga int ret; 665efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 666efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = vidioc_try_fmt_vid_cap(file, priv, f); 667efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) 668efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return ret; 669efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 6708dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (vb2_is_busy(&vip->vb_vidq)) { 6718dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Can't change format during acquisition */ 6728dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga v4l2_err(&vip->v4l2_dev, "device busy\n"); 6738dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return -EBUSY; 6748dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga } 6758dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->format = f->fmt.pix; 6768dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga switch (vip->format.field) { 6778dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga case V4L2_FIELD_INTERLACED: 6788dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga t_stop = ((vip->format.height / 2 - 1) << 16) | 6798dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga (2 * vip->format.width - 1); 6808dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga b_stop = t_stop; 6818dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga pitch = 4 * vip->format.width; 6828dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga break; 6838dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga case V4L2_FIELD_TOP: 6848dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga t_stop = ((vip->format.height - 1) << 16) | 6858dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga (2 * vip->format.width - 1); 6868dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga b_stop = (0 << 16) | (2 * vip->format.width - 1); 6878dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga pitch = 2 * vip->format.width; 6888dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga break; 6898dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga case V4L2_FIELD_BOTTOM: 6908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga t_stop = (0 << 16) | (2 * vip->format.width - 1); 6918dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga b_stop = (vip->format.height << 16) | 6928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga (2 * vip->format.width - 1); 6938dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga pitch = 2 * vip->format.width; 6948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga break; 6958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga default: 6968dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga v4l2_err(&vip->v4l2_dev, "unknown field format\n"); 6978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return -EINVAL; 6988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga } 6998dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 7008dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga spin_lock_irq(&vip->slock); 7018dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Y-X Top Field Offset */ 7028dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_TFO, 0); 7038dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Y-X Bottom Field Offset */ 7048dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_BFO, 0); 7058dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Y-X Top Field Stop*/ 7068dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_TFS, t_stop); 7078dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Y-X Bottom Field Stop */ 7088dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_BFS, b_stop); 7098dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Video Memory Pitch */ 7108dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_VMP, pitch); 7118dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga spin_unlock_irq(&vip->slock); 7128dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 713efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 714efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 715efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 716efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 717efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vidioc_g_fmt_vid_cap - get current video format parameters 7188dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * @file: descriptor of device 719efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @f: contains format information 720efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 721efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * returns current video format parameters 722efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 723efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, always successful 724efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 725efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 726efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct v4l2_format *f) 727efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 7288dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga struct sta2x11_vip *vip = video_drvdata(file); 729efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 7308dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga f->fmt.pix = vip->format; 731efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 7328dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return 0; 733efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 734efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 735efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic const struct v4l2_ioctl_ops vip_ioctl_ops = { 736efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .vidioc_querycap = vidioc_querycap, 7378dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* FMT handling */ 7388dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 7398dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 7408dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 7418dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 7428dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Buffer handlers */ 7438dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_create_bufs = vb2_ioctl_create_bufs, 7448dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_prepare_buf = vb2_ioctl_prepare_buf, 7458dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_reqbufs = vb2_ioctl_reqbufs, 7468dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_querybuf = vb2_ioctl_querybuf, 7478dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_qbuf = vb2_ioctl_qbuf, 7488dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_dqbuf = vb2_ioctl_dqbuf, 7498dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Stream on/off */ 7508dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_streamon = vb2_ioctl_streamon, 7518dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_streamoff = vb2_ioctl_streamoff, 7528dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Standard handling */ 753efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .vidioc_g_std = vidioc_g_std, 7548dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_s_std = vidioc_s_std, 755efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .vidioc_querystd = vidioc_querystd, 7568dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Input handling */ 757efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .vidioc_enum_input = vidioc_enum_input, 758efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .vidioc_g_input = vidioc_g_input, 7598dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_s_input = vidioc_s_input, 7608dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Log status ioctl */ 7618dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_log_status = v4l2_ctrl_log_status, 7628dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Event handling */ 7638dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 7648dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 765efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}; 766efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 767efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct video_device video_dev_template = { 7688dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .name = KBUILD_MODNAME, 769efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .release = video_device_release, 770efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .fops = &vip_fops, 771efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .ioctl_ops = &vip_ioctl_ops, 772efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .tvnorms = V4L2_STD_ALL, 773efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}; 774efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 775efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 776efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_irq - interrupt routine 777efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @irq: Number of interrupt ( not used, correct number is assumed ) 778efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @vip: local data structure containing all information 779efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 780efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * check for both frame interrupts set ( top and bottom ). 781efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * check FIFO overflow, but limit number of log messages after open. 7828dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * signal a complete buffer if done 783efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 784efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: IRQ_NONE, interrupt was not generated by VIP 785efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 786efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * IRQ_HANDLED, interrupt done. 787efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 788efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip) 789efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 7908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga unsigned int status; 791efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 7928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga status = reg_read(vip, DVP_ITS); 793efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 7948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (!status) /* No interrupt to handle */ 795efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return IRQ_NONE; 796efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 7978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (status & DVP_IT_FIFO) 7988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (vip->overflow++ > 5) 7998dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga pr_info("VIP: fifo overflow\n"); 800efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 8018dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if ((status & DVP_IT_VST) && (status & DVP_IT_VSB)) { 802efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga /* this is bad, we are too slow, hope the condition is gone 803efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * on the next frame */ 804efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return IRQ_HANDLED; 805efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 806efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 8078dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (status & DVP_IT_VST) 8088dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if ((++vip->tcount) < 2) 8098dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return IRQ_HANDLED; 8108dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (status & DVP_IT_VSB) { 8118dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->bcount++; 8128dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return IRQ_HANDLED; 813efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 814efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 8158dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (vip->active) { /* Acquisition is over on this buffer */ 8168dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Disable acquisition */ 8178dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_CTL, reg_read(vip, DVP_CTL) & ~DVP_CTL_ENA); 8188dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Remove the active buffer from the list */ 8198dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga do_gettimeofday(&vip->active->vb.v4l2_buf.timestamp); 8208dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->active->vb.v4l2_buf.sequence = vip->sequence++; 8218dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vb2_buffer_done(&vip->active->vb, VB2_BUF_STATE_DONE); 8228dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga } 823efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 8248dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return IRQ_HANDLED; 8258dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga} 826efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 8278dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic void sta2x11_vip_init_register(struct sta2x11_vip *vip) 8288dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{ 8298dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Register initialization */ 8308dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga spin_lock_irq(&vip->slock); 8318dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Clean interrupt */ 8328dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_read(vip, DVP_ITS); 8338dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Enable Half Line per vertical */ 8348dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_HLFLN, DVP_HLFLN_SD); 8358dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Reset VIP control */ 8368dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_CTL, DVP_CTL_RST); 8378dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Clear VIP control */ 8388dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_CTL, 0); 8398dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga spin_unlock_irq(&vip->slock); 8408dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga} 8418dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic void sta2x11_vip_clear_register(struct sta2x11_vip *vip) 8428dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{ 8438dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga spin_lock_irq(&vip->slock); 8448dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Disable interrupt */ 8458dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_ITM, 0); 8468dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Reset VIP Control */ 8478dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_CTL, DVP_CTL_RST); 8488dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Clear VIP Control */ 8498dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_CTL, 0); 8508dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Clean VIP Interrupt */ 8518dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_read(vip, DVP_ITS); 8528dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga spin_unlock_irq(&vip->slock); 8538dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga} 8548dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int sta2x11_vip_init_buffer(struct sta2x11_vip *vip) 8558dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{ 8568dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga int err; 857efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 8588dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga err = dma_set_coherent_mask(&vip->pdev->dev, DMA_BIT_MASK(29)); 8598dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (err) { 8608dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga v4l2_err(&vip->v4l2_dev, "Cannot configure coherent mask"); 8618dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return err; 862efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 8638dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga memset(&vip->vb_vidq, 0, sizeof(struct vb2_queue)); 8648dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->vb_vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 8658dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->vb_vidq.io_modes = VB2_MMAP | VB2_READ; 8668dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->vb_vidq.drv_priv = vip; 8678dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->vb_vidq.buf_struct_size = sizeof(struct vip_buffer); 8688dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->vb_vidq.ops = &vip_video_qops; 8698dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->vb_vidq.mem_ops = &vb2_dma_contig_memops; 8708dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga err = vb2_queue_init(&vip->vb_vidq); 8718dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (err) 8728dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return err; 8738dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga INIT_LIST_HEAD(&vip->buffer_list); 8748dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga spin_lock_init(&vip->lock); 8758dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 8768dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 8778dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->alloc_ctx = vb2_dma_contig_init_ctx(&vip->pdev->dev); 8788dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (IS_ERR(vip->alloc_ctx)) { 8798dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga v4l2_err(&vip->v4l2_dev, "Can't allocate buffer context"); 8808dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return PTR_ERR(vip->alloc_ctx); 881efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 8828dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 8838dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return 0; 8848dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga} 8858dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic void sta2x11_vip_release_buffer(struct sta2x11_vip *vip) 8868dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{ 8878dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vb2_dma_contig_cleanup_ctx(vip->alloc_ctx); 8888dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga} 8898dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagastatic int sta2x11_vip_init_controls(struct sta2x11_vip *vip) 8908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga{ 8918dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* 8928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * Inititialize an empty control so VIP can inerithing controls 8938dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga * from ADV7180 8948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga */ 8958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga v4l2_ctrl_handler_init(&vip->ctrl_hdl, 0); 8968dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 8978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->v4l2_dev.ctrl_handler = &vip->ctrl_hdl; 8988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (vip->ctrl_hdl.error) { 8998dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga int err = vip->ctrl_hdl.error; 9008dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 9018dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga v4l2_ctrl_handler_free(&vip->ctrl_hdl); 9028dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return err; 9038dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga } 9048dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 9058dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return 0; 906efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 907efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 908efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 909efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_gpio_reserve - reserve gpio pin 910efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @dev: device 911efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pin: GPIO pin number 912efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @dir: direction, input or output 913efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @name: GPIO pin name 914efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 915efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 916efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int vip_gpio_reserve(struct device *dev, int pin, int dir, 917efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga const char *name) 918efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 919efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga int ret; 920efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 921efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (pin == -1) 922efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 923efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 924efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = gpio_request(pin, name); 925efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) { 926efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga dev_err(dev, "Failed to allocate pin %d (%s)\n", pin, name); 927efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return ret; 928efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 929efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 930efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = gpio_direction_output(pin, dir); 931efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) { 932efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga dev_err(dev, "Failed to set direction for pin %d (%s)\n", 933efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pin, name); 934efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga gpio_free(pin); 935efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return ret; 936efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 937efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 938efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = gpio_export(pin, false); 939efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) { 940efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga dev_err(dev, "Failed to export pin %d (%s)\n", pin, name); 941efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga gpio_free(pin); 942efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return ret; 943efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 944efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 945efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 946efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 947efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 948efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 949efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * vip_gpio_release - release gpio pin 950efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @dev: device 951efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pin: GPIO pin number 952efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @name: GPIO pin name 953efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 954efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 955efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic void vip_gpio_release(struct device *dev, int pin, const char *name) 956efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 957efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (pin != -1) { 958efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga dev_dbg(dev, "releasing pin %d (%s)\n", pin, name); 959efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga gpio_unexport(pin); 960efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga gpio_free(pin); 961efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 962efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 963efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 964efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 965efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_init_one - init one instance of video device 966efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device 967efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @ent: (not used) 968efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 969efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * allocate reset pins for DAC. 970efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Reset video DAC, this is done via reset line. 971efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * allocate memory for managing device 972efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * request interrupt 973efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * map IO region 974efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * register device 975efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * find and initialize video DAC 976efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 977efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error 978efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 979efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -ENOMEM, no memory 980efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 981efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * -ENODEV, device could not be detected or registered 982efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 9834c62e9764ab403d42f9b8871b1241fe7812f19d4Greg Kroah-Hartmanstatic int sta2x11_vip_init_one(struct pci_dev *pdev, 9844c62e9764ab403d42f9b8871b1241fe7812f19d4Greg Kroah-Hartman const struct pci_device_id *ent) 985efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 986efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga int ret; 987efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct sta2x11_vip *vip; 988efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct vip_config *config; 989efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 9908dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Check if hardware support 26-bit DMA */ 9918dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(26))) { 9928dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga dev_err(&pdev->dev, "26-bit DMA addressing not available\n"); 9938dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga return -EINVAL; 9948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga } 9958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Enable PCI */ 996efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = pci_enable_device(pdev); 997efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) 998efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return ret; 999efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 10008dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Get VIP platform data */ 1001efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga config = dev_get_platdata(&pdev->dev); 1002efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (!config) { 1003efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga dev_info(&pdev->dev, "VIP slot disabled\n"); 1004efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = -EINVAL; 1005efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto disable; 1006efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1007efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 10088dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Power configuration */ 1009efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = vip_gpio_reserve(&pdev->dev, config->pwr_pin, 0, 1010efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga config->pwr_name); 1011efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) 1012efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto disable; 1013efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1014efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (config->reset_pin >= 0) { 1015efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = vip_gpio_reserve(&pdev->dev, config->reset_pin, 0, 1016efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga config->reset_name); 1017efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) { 1018efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip_gpio_release(&pdev->dev, config->pwr_pin, 1019efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga config->pwr_name); 1020efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto disable; 1021efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1022efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1023efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (config->pwr_pin != -1) { 1024efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga /* Datasheet says 5ms between PWR and RST */ 1025efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga usleep_range(5000, 25000); 1026efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = gpio_direction_output(config->pwr_pin, 1); 1027efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1028efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1029efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (config->reset_pin != -1) { 1030efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga /* Datasheet says 5ms between PWR and RST */ 1031efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga usleep_range(5000, 25000); 1032efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = gpio_direction_output(config->reset_pin, 1); 1033efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1034efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga usleep_range(5000, 25000); 1035efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 10368dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Allocate a new VIP instance */ 1037efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip = kzalloc(sizeof(struct sta2x11_vip), GFP_KERNEL); 1038efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (!vip) { 1039efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = -ENOMEM; 1040efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto release_gpios; 1041efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1042efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->pdev = pdev; 1043efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->std = V4L2_STD_PAL; 1044efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->format = formats_50[0]; 1045efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->config = config; 1046efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 10478dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga ret = sta2x11_vip_init_controls(vip); 10488dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (ret) 10498dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga goto free_mem; 1050d017650b40b4cb5c4158e3b9af38af164986b022Wei Yongjun ret = v4l2_device_register(&pdev->dev, &vip->v4l2_dev); 1051d017650b40b4cb5c4158e3b9af38af164986b022Wei Yongjun if (ret) 1052efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto free_mem; 1053efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1054efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga dev_dbg(&pdev->dev, "BAR #0 at 0x%lx 0x%lx irq %d\n", 1055efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga (unsigned long)pci_resource_start(pdev, 0), 1056efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga (unsigned long)pci_resource_len(pdev, 0), pdev->irq); 1057efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1058efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_set_master(pdev); 1059efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 10608dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga ret = pci_request_regions(pdev, KBUILD_MODNAME); 1061efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) 1062efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto unreg; 1063efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1064efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->iomem = pci_iomap(pdev, 0, 0x100); 1065efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (!vip->iomem) { 10668dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga ret = -ENOMEM; 1067efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto release; 1068efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1069efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1070efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_enable_msi(pdev); 1071efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 10728dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Initialize buffer */ 10738dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga ret = sta2x11_vip_init_buffer(vip); 10748dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga if (ret) 10758dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga goto unmap; 10768dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 1077efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga spin_lock_init(&vip->slock); 1078efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1079efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = request_irq(pdev->irq, 1080efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga (irq_handler_t) vip_irq, 10818dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga IRQF_SHARED, KBUILD_MODNAME, vip); 1082efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) { 1083efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga dev_err(&pdev->dev, "request_irq failed\n"); 1084efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = -ENODEV; 10858dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga goto release_buf; 1086efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1087efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 10888dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Alloc, initialize and register video device */ 1089efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->video_dev = video_device_alloc(); 1090efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (!vip->video_dev) { 1091efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = -ENOMEM; 1092efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto release_irq; 1093efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1094efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 10958dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->video_dev = &video_dev_template; 10968dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->video_dev->v4l2_dev = &vip->v4l2_dev; 10978dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->video_dev->queue = &vip->vb_vidq; 10988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga set_bit(V4L2_FL_USE_FH_PRIO, &vip->video_dev->flags); 1099efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga video_set_drvdata(vip->video_dev, vip); 1100efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1101efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = video_register_device(vip->video_dev, VFL_TYPE_GRABBER, -1); 1102efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) 1103efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto vrelease; 1104efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 11058dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga /* Get ADV7180 subdevice */ 1106efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->adapter = i2c_get_adapter(vip->config->i2c_id); 1107efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (!vip->adapter) { 1108efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = -ENODEV; 1109efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga dev_err(&pdev->dev, "no I2C adapter found\n"); 1110efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto vunreg; 1111efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1112efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1113efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->decoder = v4l2_i2c_new_subdev(&vip->v4l2_dev, vip->adapter, 1114efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga "adv7180", vip->config->i2c_addr, 1115efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga NULL); 1116efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (!vip->decoder) { 1117efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = -ENODEV; 1118efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga dev_err(&pdev->dev, "no decoder found\n"); 1119efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga goto vunreg; 1120efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1121efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1122efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga i2c_put_adapter(vip->adapter); 1123efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga v4l2_subdev_call(vip->decoder, core, init, 0); 1124efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 11258dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga sta2x11_vip_init_register(vip); 11268dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 11278dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga dev_info(&pdev->dev, "STA2X11 Video Input Port (VIP) loaded\n"); 1128efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 1129efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1130efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagavunreg: 1131efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga video_set_drvdata(vip->video_dev, NULL); 1132efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagavrelease: 1133efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (video_is_registered(vip->video_dev)) 1134efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga video_unregister_device(vip->video_dev); 1135efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga else 1136efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga video_device_release(vip->video_dev); 1137efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagarelease_irq: 1138efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga free_irq(pdev->irq, vip); 11398dc97ea20c2bdf406348640abbd35eb89c843957Federico Vagarelease_buf: 11408dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga sta2x11_vip_release_buffer(vip); 1141efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_disable_msi(pdev); 1142efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagaunmap: 11438dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vb2_queue_release(&vip->vb_vidq); 1144efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_iounmap(pdev, vip->iomem); 1145efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagarelease: 1146efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_release_regions(pdev); 1147efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagaunreg: 1148efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga v4l2_device_unregister(&vip->v4l2_dev); 1149efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagafree_mem: 1150efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga kfree(vip); 1151efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagarelease_gpios: 1152efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip_gpio_release(&pdev->dev, config->reset_pin, config->reset_name); 1153efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip_gpio_release(&pdev->dev, config->pwr_pin, config->pwr_name); 1154efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagadisable: 1155efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga /* 1156efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * do not call pci_disable_device on sta2x11 because it break all 1157efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other Bus masters on this EP 1158efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 1159efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return ret; 1160efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 1161efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1162efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 1163efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_remove_one - release device 1164efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device 1165efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 1166efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * Undo everything done in .._init_one 1167efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 1168efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * unregister video device 1169efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * free interrupt 1170efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * unmap ioadresses 1171efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * free memory 1172efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * free GPIO pins 1173efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 11744c62e9764ab403d42f9b8871b1241fe7812f19d4Greg Kroah-Hartmanstatic void sta2x11_vip_remove_one(struct pci_dev *pdev) 1175efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 1176efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); 1177efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct sta2x11_vip *vip = 1178efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev); 1179efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 11808dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga sta2x11_vip_clear_register(vip); 11818dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga 1182efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga video_set_drvdata(vip->video_dev, NULL); 1183efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga video_unregister_device(vip->video_dev); 1184efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga /*do not call video_device_release() here, is already done */ 1185efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga free_irq(pdev->irq, vip); 1186efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_disable_msi(pdev); 11878dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vb2_queue_release(&vip->vb_vidq); 1188efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_iounmap(pdev, vip->iomem); 1189efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_release_regions(pdev); 1190efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1191efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga v4l2_device_unregister(&vip->v4l2_dev); 1192efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1193efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip_gpio_release(&pdev->dev, vip->config->pwr_pin, 1194efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->config->pwr_name); 1195efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip_gpio_release(&pdev->dev, vip->config->reset_pin, 1196efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->config->reset_name); 1197efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1198efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga kfree(vip); 1199efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga /* 1200efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * do not call pci_disable_device on sta2x11 because it break all 1201efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other Bus masters on this EP 1202efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 1203efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 1204efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1205efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifdef CONFIG_PM 1206efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1207efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 1208efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_suspend - set device into power save mode 1209efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev: PCI device 1210efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @state: new state of device 1211efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 1212efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * all relevant registers are saved and an attempt to set a new state is made. 1213efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 1214efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0 always indicate success, 1215efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * even if device could not be disabled. (workaround for hardware problem) 1216efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 1217efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int sta2x11_vip_suspend(struct pci_dev *pdev, pm_message_t state) 1218efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 1219efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); 1220efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct sta2x11_vip *vip = 1221efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev); 1222efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga unsigned long flags; 1223efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga int i; 1224efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1225efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga spin_lock_irqsave(&vip->slock, flags); 12268dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->register_save_area[0] = reg_read(vip, DVP_CTL); 12278dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_CTL, vip->register_save_area[0] & DVP_CTL_DIS); 12288dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->register_save_area[SAVE_COUNT] = reg_read(vip, DVP_ITM); 12298dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_ITM, 0); 1230efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga for (i = 1; i < SAVE_COUNT; i++) 12318dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga vip->register_save_area[i] = reg_read(vip, 4 * i); 1232efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga for (i = 0; i < AUX_COUNT; i++) 1233efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i] = 12348dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_read(vip, registers_to_save[i]); 1235efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga spin_unlock_irqrestore(&vip->slock, flags); 1236efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga /* save pci state */ 1237efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_save_state(pdev); 1238efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (pci_set_power_state(pdev, pci_choose_state(pdev, state))) { 1239efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga /* 1240efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * do not call pci_disable_device on sta2x11 because it 1241efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * break all other Bus masters on this EP 1242efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 1243efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->disabled = 1; 1244efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1245efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1246efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pr_info("VIP: suspend\n"); 1247efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 1248efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 1249efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1250efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga/** 1251efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * sta2x11_vip_resume - resume device operation 1252efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * @pdev : PCI device 1253efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 1254efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * re-enable device, set PCI state to powered and restore registers. 1255efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * resume normal device operation afterwards. 1256efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 1257efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * return value: 0, no error. 1258efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * 1259efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * other, could not set device to power on state. 1260efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 1261efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int sta2x11_vip_resume(struct pci_dev *pdev) 1262efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 1263efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); 1264efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga struct sta2x11_vip *vip = 1265efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev); 1266efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga unsigned long flags; 1267efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga int ret, i; 1268efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1269efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pr_info("VIP: resume\n"); 1270efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga /* restore pci state */ 1271efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (vip->disabled) { 1272efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = pci_enable_device(pdev); 1273efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) { 12748dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga pr_warn("VIP: Can't enable device.\n"); 1275efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return ret; 1276efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1277efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->disabled = 0; 1278efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1279efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga ret = pci_set_power_state(pdev, PCI_D0); 1280efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga if (ret) { 1281efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga /* 1282efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * do not call pci_disable_device on sta2x11 because it 1283efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga * break all other Bus masters on this EP 1284efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga */ 12858dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga pr_warn("VIP: Can't enable device.\n"); 1286efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->disabled = 1; 1287efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return ret; 1288efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga } 1289efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1290efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_restore_state(pdev); 1291efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1292efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga spin_lock_irqsave(&vip->slock, flags); 1293efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga for (i = 1; i < SAVE_COUNT; i++) 12948dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, 4 * i, vip->register_save_area[i]); 1295efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga for (i = 0; i < AUX_COUNT; i++) 12968dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, registers_to_save[i], 1297efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i]); 12988dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_CTL, vip->register_save_area[0]); 12998dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga reg_write(vip, DVP_ITM, vip->register_save_area[SAVE_COUNT]); 1300efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga spin_unlock_irqrestore(&vip->slock, flags); 1301efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return 0; 1302efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 1303efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1304efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif 1305efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1306efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic DEFINE_PCI_DEVICE_TABLE(sta2x11_vip_pci_tbl) = { 1307efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIP)}, 1308efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga {0,} 1309efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}; 1310efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1311efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic struct pci_driver sta2x11_vip_driver = { 13128dc97ea20c2bdf406348640abbd35eb89c843957Federico Vaga .name = KBUILD_MODNAME, 1313efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .probe = sta2x11_vip_init_one, 13144c62e9764ab403d42f9b8871b1241fe7812f19d4Greg Kroah-Hartman .remove = sta2x11_vip_remove_one, 1315efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .id_table = sta2x11_vip_pci_tbl, 1316efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifdef CONFIG_PM 1317efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .suspend = sta2x11_vip_suspend, 1318efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga .resume = sta2x11_vip_resume, 1319efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif 1320efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga}; 1321efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1322efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic int __init sta2x11_vip_init_module(void) 1323efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 1324efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga return pci_register_driver(&sta2x11_vip_driver); 1325efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 1326efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1327efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagastatic void __exit sta2x11_vip_exit_module(void) 1328efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga{ 1329efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga pci_unregister_driver(&sta2x11_vip_driver); 1330efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga} 1331efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1332efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#ifdef MODULE 1333efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagamodule_init(sta2x11_vip_init_module); 1334efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagamodule_exit(sta2x11_vip_exit_module); 1335efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#else 1336efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vagalate_initcall_sync(sta2x11_vip_init_module); 1337efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga#endif 1338efeb98b4e2b2ce50e008affce4c493e58167144aFederico Vaga 1339efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_DESCRIPTION("STA2X11 Video Input Port driver"); 1340efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_AUTHOR("Wind River"); 1341efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_LICENSE("GPL v2"); 1342efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_SUPPORTED_DEVICE("sta2x11 video input"); 1343efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_VERSION(DRV_VERSION); 1344efeb98b4e2b2ce50e008affce4c493e58167144aFederico VagaMODULE_DEVICE_TABLE(pci, sta2x11_vip_pci_tbl); 1345