1*0185f850SArnd Bergmann /* 2*0185f850SArnd Bergmann * This is a V4L2 PCI Skeleton Driver. It gives an initial skeleton source 3*0185f850SArnd Bergmann * for use with other PCI drivers. 4*0185f850SArnd Bergmann * 5*0185f850SArnd Bergmann * This skeleton PCI driver assumes that the card has an S-Video connector as 6*0185f850SArnd Bergmann * input 0 and an HDMI connector as input 1. 7*0185f850SArnd Bergmann * 8*0185f850SArnd Bergmann * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 9*0185f850SArnd Bergmann * 10*0185f850SArnd Bergmann * This program is free software; you may redistribute it and/or modify 11*0185f850SArnd Bergmann * it under the terms of the GNU General Public License as published by 12*0185f850SArnd Bergmann * the Free Software Foundation; version 2 of the License. 13*0185f850SArnd Bergmann * 14*0185f850SArnd Bergmann * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15*0185f850SArnd Bergmann * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16*0185f850SArnd Bergmann * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17*0185f850SArnd Bergmann * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 18*0185f850SArnd Bergmann * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 19*0185f850SArnd Bergmann * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20*0185f850SArnd Bergmann * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21*0185f850SArnd Bergmann * SOFTWARE. 22*0185f850SArnd Bergmann */ 23*0185f850SArnd Bergmann 24*0185f850SArnd Bergmann #include <linux/types.h> 25*0185f850SArnd Bergmann #include <linux/kernel.h> 26*0185f850SArnd Bergmann #include <linux/module.h> 27*0185f850SArnd Bergmann #include <linux/init.h> 28*0185f850SArnd Bergmann #include <linux/kmod.h> 29*0185f850SArnd Bergmann #include <linux/mutex.h> 30*0185f850SArnd Bergmann #include <linux/pci.h> 31*0185f850SArnd Bergmann #include <linux/interrupt.h> 32*0185f850SArnd Bergmann #include <linux/videodev2.h> 33*0185f850SArnd Bergmann #include <linux/v4l2-dv-timings.h> 34*0185f850SArnd Bergmann #include <media/v4l2-device.h> 35*0185f850SArnd Bergmann #include <media/v4l2-dev.h> 36*0185f850SArnd Bergmann #include <media/v4l2-ioctl.h> 37*0185f850SArnd Bergmann #include <media/v4l2-dv-timings.h> 38*0185f850SArnd Bergmann #include <media/v4l2-ctrls.h> 39*0185f850SArnd Bergmann #include <media/v4l2-event.h> 40*0185f850SArnd Bergmann #include <media/videobuf2-v4l2.h> 41*0185f850SArnd Bergmann #include <media/videobuf2-dma-contig.h> 42*0185f850SArnd Bergmann 43*0185f850SArnd Bergmann MODULE_DESCRIPTION("V4L2 PCI Skeleton Driver"); 44*0185f850SArnd Bergmann MODULE_AUTHOR("Hans Verkuil"); 45*0185f850SArnd Bergmann MODULE_LICENSE("GPL v2"); 46*0185f850SArnd Bergmann 47*0185f850SArnd Bergmann /** 48*0185f850SArnd Bergmann * struct skeleton - All internal data for one instance of device 49*0185f850SArnd Bergmann * @pdev: PCI device 50*0185f850SArnd Bergmann * @v4l2_dev: top-level v4l2 device struct 51*0185f850SArnd Bergmann * @vdev: video node structure 52*0185f850SArnd Bergmann * @ctrl_handler: control handler structure 53*0185f850SArnd Bergmann * @lock: ioctl serialization mutex 54*0185f850SArnd Bergmann * @std: current SDTV standard 55*0185f850SArnd Bergmann * @timings: current HDTV timings 56*0185f850SArnd Bergmann * @format: current pix format 57*0185f850SArnd Bergmann * @input: current video input (0 = SDTV, 1 = HDTV) 58*0185f850SArnd Bergmann * @queue: vb2 video capture queue 59*0185f850SArnd Bergmann * @alloc_ctx: vb2 contiguous DMA context 60*0185f850SArnd Bergmann * @qlock: spinlock controlling access to buf_list and sequence 61*0185f850SArnd Bergmann * @buf_list: list of buffers queued for DMA 62*0185f850SArnd Bergmann * @sequence: frame sequence counter 63*0185f850SArnd Bergmann */ 64*0185f850SArnd Bergmann struct skeleton { 65*0185f850SArnd Bergmann struct pci_dev *pdev; 66*0185f850SArnd Bergmann struct v4l2_device v4l2_dev; 67*0185f850SArnd Bergmann struct video_device vdev; 68*0185f850SArnd Bergmann struct v4l2_ctrl_handler ctrl_handler; 69*0185f850SArnd Bergmann struct mutex lock; 70*0185f850SArnd Bergmann v4l2_std_id std; 71*0185f850SArnd Bergmann struct v4l2_dv_timings timings; 72*0185f850SArnd Bergmann struct v4l2_pix_format format; 73*0185f850SArnd Bergmann unsigned input; 74*0185f850SArnd Bergmann 75*0185f850SArnd Bergmann struct vb2_queue queue; 76*0185f850SArnd Bergmann struct vb2_alloc_ctx *alloc_ctx; 77*0185f850SArnd Bergmann 78*0185f850SArnd Bergmann spinlock_t qlock; 79*0185f850SArnd Bergmann struct list_head buf_list; 80*0185f850SArnd Bergmann unsigned field; 81*0185f850SArnd Bergmann unsigned sequence; 82*0185f850SArnd Bergmann }; 83*0185f850SArnd Bergmann 84*0185f850SArnd Bergmann struct skel_buffer { 85*0185f850SArnd Bergmann struct vb2_buffer vb; 86*0185f850SArnd Bergmann struct list_head list; 87*0185f850SArnd Bergmann }; 88*0185f850SArnd Bergmann 89*0185f850SArnd Bergmann static inline struct skel_buffer *to_skel_buffer(struct vb2_buffer *vb2) 90*0185f850SArnd Bergmann { 91*0185f850SArnd Bergmann return container_of(vb2, struct skel_buffer, vb); 92*0185f850SArnd Bergmann } 93*0185f850SArnd Bergmann 94*0185f850SArnd Bergmann static const struct pci_device_id skeleton_pci_tbl[] = { 95*0185f850SArnd Bergmann /* { PCI_DEVICE(PCI_VENDOR_ID_, PCI_DEVICE_ID_) }, */ 96*0185f850SArnd Bergmann { 0, } 97*0185f850SArnd Bergmann }; 98*0185f850SArnd Bergmann MODULE_DEVICE_TABLE(pci, skeleton_pci_tbl); 99*0185f850SArnd Bergmann 100*0185f850SArnd Bergmann /* 101*0185f850SArnd Bergmann * HDTV: this structure has the capabilities of the HDTV receiver. 102*0185f850SArnd Bergmann * It is used to constrain the huge list of possible formats based 103*0185f850SArnd Bergmann * upon the hardware capabilities. 104*0185f850SArnd Bergmann */ 105*0185f850SArnd Bergmann static const struct v4l2_dv_timings_cap skel_timings_cap = { 106*0185f850SArnd Bergmann .type = V4L2_DV_BT_656_1120, 107*0185f850SArnd Bergmann /* keep this initialization for compatibility with GCC < 4.4.6 */ 108*0185f850SArnd Bergmann .reserved = { 0 }, 109*0185f850SArnd Bergmann V4L2_INIT_BT_TIMINGS( 110*0185f850SArnd Bergmann 720, 1920, /* min/max width */ 111*0185f850SArnd Bergmann 480, 1080, /* min/max height */ 112*0185f850SArnd Bergmann 27000000, 74250000, /* min/max pixelclock*/ 113*0185f850SArnd Bergmann V4L2_DV_BT_STD_CEA861, /* Supported standards */ 114*0185f850SArnd Bergmann /* capabilities */ 115*0185f850SArnd Bergmann V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_PROGRESSIVE 116*0185f850SArnd Bergmann ) 117*0185f850SArnd Bergmann }; 118*0185f850SArnd Bergmann 119*0185f850SArnd Bergmann /* 120*0185f850SArnd Bergmann * Supported SDTV standards. This does the same job as skel_timings_cap, but 121*0185f850SArnd Bergmann * for standard TV formats. 122*0185f850SArnd Bergmann */ 123*0185f850SArnd Bergmann #define SKEL_TVNORMS V4L2_STD_ALL 124*0185f850SArnd Bergmann 125*0185f850SArnd Bergmann /* 126*0185f850SArnd Bergmann * Interrupt handler: typically interrupts happen after a new frame has been 127*0185f850SArnd Bergmann * captured. It is the job of the handler to remove the new frame from the 128*0185f850SArnd Bergmann * internal list and give it back to the vb2 framework, updating the sequence 129*0185f850SArnd Bergmann * counter, field and timestamp at the same time. 130*0185f850SArnd Bergmann */ 131*0185f850SArnd Bergmann static irqreturn_t skeleton_irq(int irq, void *dev_id) 132*0185f850SArnd Bergmann { 133*0185f850SArnd Bergmann #ifdef TODO 134*0185f850SArnd Bergmann struct skeleton *skel = dev_id; 135*0185f850SArnd Bergmann 136*0185f850SArnd Bergmann /* handle interrupt */ 137*0185f850SArnd Bergmann 138*0185f850SArnd Bergmann /* Once a new frame has been captured, mark it as done like this: */ 139*0185f850SArnd Bergmann if (captured_new_frame) { 140*0185f850SArnd Bergmann ... 141*0185f850SArnd Bergmann spin_lock(&skel->qlock); 142*0185f850SArnd Bergmann list_del(&new_buf->list); 143*0185f850SArnd Bergmann spin_unlock(&skel->qlock); 144*0185f850SArnd Bergmann v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp); 145*0185f850SArnd Bergmann new_buf->vb.v4l2_buf.sequence = skel->sequence++; 146*0185f850SArnd Bergmann new_buf->vb.v4l2_buf.field = skel->field; 147*0185f850SArnd Bergmann if (skel->format.field == V4L2_FIELD_ALTERNATE) { 148*0185f850SArnd Bergmann if (skel->field == V4L2_FIELD_BOTTOM) 149*0185f850SArnd Bergmann skel->field = V4L2_FIELD_TOP; 150*0185f850SArnd Bergmann else if (skel->field == V4L2_FIELD_TOP) 151*0185f850SArnd Bergmann skel->field = V4L2_FIELD_BOTTOM; 152*0185f850SArnd Bergmann } 153*0185f850SArnd Bergmann vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE); 154*0185f850SArnd Bergmann } 155*0185f850SArnd Bergmann #endif 156*0185f850SArnd Bergmann return IRQ_HANDLED; 157*0185f850SArnd Bergmann } 158*0185f850SArnd Bergmann 159*0185f850SArnd Bergmann /* 160*0185f850SArnd Bergmann * Setup the constraints of the queue: besides setting the number of planes 161*0185f850SArnd Bergmann * per buffer and the size and allocation context of each plane, it also 162*0185f850SArnd Bergmann * checks if sufficient buffers have been allocated. Usually 3 is a good 163*0185f850SArnd Bergmann * minimum number: many DMA engines need a minimum of 2 buffers in the 164*0185f850SArnd Bergmann * queue and you need to have another available for userspace processing. 165*0185f850SArnd Bergmann */ 166*0185f850SArnd Bergmann static int queue_setup(struct vb2_queue *vq, 167*0185f850SArnd Bergmann unsigned int *nbuffers, unsigned int *nplanes, 168*0185f850SArnd Bergmann unsigned int sizes[], void *alloc_ctxs[]) 169*0185f850SArnd Bergmann { 170*0185f850SArnd Bergmann struct skeleton *skel = vb2_get_drv_priv(vq); 171*0185f850SArnd Bergmann 172*0185f850SArnd Bergmann skel->field = skel->format.field; 173*0185f850SArnd Bergmann if (skel->field == V4L2_FIELD_ALTERNATE) { 174*0185f850SArnd Bergmann /* 175*0185f850SArnd Bergmann * You cannot use read() with FIELD_ALTERNATE since the field 176*0185f850SArnd Bergmann * information (TOP/BOTTOM) cannot be passed back to the user. 177*0185f850SArnd Bergmann */ 178*0185f850SArnd Bergmann if (vb2_fileio_is_active(vq)) 179*0185f850SArnd Bergmann return -EINVAL; 180*0185f850SArnd Bergmann skel->field = V4L2_FIELD_TOP; 181*0185f850SArnd Bergmann } 182*0185f850SArnd Bergmann 183*0185f850SArnd Bergmann if (vq->num_buffers + *nbuffers < 3) 184*0185f850SArnd Bergmann *nbuffers = 3 - vq->num_buffers; 185*0185f850SArnd Bergmann alloc_ctxs[0] = skel->alloc_ctx; 186*0185f850SArnd Bergmann 187*0185f850SArnd Bergmann if (*nplanes) 188*0185f850SArnd Bergmann return sizes[0] < skel->format.sizeimage ? -EINVAL : 0; 189*0185f850SArnd Bergmann *nplanes = 1; 190*0185f850SArnd Bergmann sizes[0] = skel->format.sizeimage; 191*0185f850SArnd Bergmann return 0; 192*0185f850SArnd Bergmann } 193*0185f850SArnd Bergmann 194*0185f850SArnd Bergmann /* 195*0185f850SArnd Bergmann * Prepare the buffer for queueing to the DMA engine: check and set the 196*0185f850SArnd Bergmann * payload size. 197*0185f850SArnd Bergmann */ 198*0185f850SArnd Bergmann static int buffer_prepare(struct vb2_buffer *vb) 199*0185f850SArnd Bergmann { 200*0185f850SArnd Bergmann struct skeleton *skel = vb2_get_drv_priv(vb->vb2_queue); 201*0185f850SArnd Bergmann unsigned long size = skel->format.sizeimage; 202*0185f850SArnd Bergmann 203*0185f850SArnd Bergmann if (vb2_plane_size(vb, 0) < size) { 204*0185f850SArnd Bergmann dev_err(&skel->pdev->dev, "buffer too small (%lu < %lu)\n", 205*0185f850SArnd Bergmann vb2_plane_size(vb, 0), size); 206*0185f850SArnd Bergmann return -EINVAL; 207*0185f850SArnd Bergmann } 208*0185f850SArnd Bergmann 209*0185f850SArnd Bergmann vb2_set_plane_payload(vb, 0, size); 210*0185f850SArnd Bergmann return 0; 211*0185f850SArnd Bergmann } 212*0185f850SArnd Bergmann 213*0185f850SArnd Bergmann /* 214*0185f850SArnd Bergmann * Queue this buffer to the DMA engine. 215*0185f850SArnd Bergmann */ 216*0185f850SArnd Bergmann static void buffer_queue(struct vb2_buffer *vb) 217*0185f850SArnd Bergmann { 218*0185f850SArnd Bergmann struct skeleton *skel = vb2_get_drv_priv(vb->vb2_queue); 219*0185f850SArnd Bergmann struct skel_buffer *buf = to_skel_buffer(vb); 220*0185f850SArnd Bergmann unsigned long flags; 221*0185f850SArnd Bergmann 222*0185f850SArnd Bergmann spin_lock_irqsave(&skel->qlock, flags); 223*0185f850SArnd Bergmann list_add_tail(&buf->list, &skel->buf_list); 224*0185f850SArnd Bergmann 225*0185f850SArnd Bergmann /* TODO: Update any DMA pointers if necessary */ 226*0185f850SArnd Bergmann 227*0185f850SArnd Bergmann spin_unlock_irqrestore(&skel->qlock, flags); 228*0185f850SArnd Bergmann } 229*0185f850SArnd Bergmann 230*0185f850SArnd Bergmann static void return_all_buffers(struct skeleton *skel, 231*0185f850SArnd Bergmann enum vb2_buffer_state state) 232*0185f850SArnd Bergmann { 233*0185f850SArnd Bergmann struct skel_buffer *buf, *node; 234*0185f850SArnd Bergmann unsigned long flags; 235*0185f850SArnd Bergmann 236*0185f850SArnd Bergmann spin_lock_irqsave(&skel->qlock, flags); 237*0185f850SArnd Bergmann list_for_each_entry_safe(buf, node, &skel->buf_list, list) { 238*0185f850SArnd Bergmann vb2_buffer_done(&buf->vb, state); 239*0185f850SArnd Bergmann list_del(&buf->list); 240*0185f850SArnd Bergmann } 241*0185f850SArnd Bergmann spin_unlock_irqrestore(&skel->qlock, flags); 242*0185f850SArnd Bergmann } 243*0185f850SArnd Bergmann 244*0185f850SArnd Bergmann /* 245*0185f850SArnd Bergmann * Start streaming. First check if the minimum number of buffers have been 246*0185f850SArnd Bergmann * queued. If not, then return -ENOBUFS and the vb2 framework will call 247*0185f850SArnd Bergmann * this function again the next time a buffer has been queued until enough 248*0185f850SArnd Bergmann * buffers are available to actually start the DMA engine. 249*0185f850SArnd Bergmann */ 250*0185f850SArnd Bergmann static int start_streaming(struct vb2_queue *vq, unsigned int count) 251*0185f850SArnd Bergmann { 252*0185f850SArnd Bergmann struct skeleton *skel = vb2_get_drv_priv(vq); 253*0185f850SArnd Bergmann int ret = 0; 254*0185f850SArnd Bergmann 255*0185f850SArnd Bergmann skel->sequence = 0; 256*0185f850SArnd Bergmann 257*0185f850SArnd Bergmann /* TODO: start DMA */ 258*0185f850SArnd Bergmann 259*0185f850SArnd Bergmann if (ret) { 260*0185f850SArnd Bergmann /* 261*0185f850SArnd Bergmann * In case of an error, return all active buffers to the 262*0185f850SArnd Bergmann * QUEUED state 263*0185f850SArnd Bergmann */ 264*0185f850SArnd Bergmann return_all_buffers(skel, VB2_BUF_STATE_QUEUED); 265*0185f850SArnd Bergmann } 266*0185f850SArnd Bergmann return ret; 267*0185f850SArnd Bergmann } 268*0185f850SArnd Bergmann 269*0185f850SArnd Bergmann /* 270*0185f850SArnd Bergmann * Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued 271*0185f850SArnd Bergmann * and passed on to the vb2 framework marked as STATE_ERROR. 272*0185f850SArnd Bergmann */ 273*0185f850SArnd Bergmann static void stop_streaming(struct vb2_queue *vq) 274*0185f850SArnd Bergmann { 275*0185f850SArnd Bergmann struct skeleton *skel = vb2_get_drv_priv(vq); 276*0185f850SArnd Bergmann 277*0185f850SArnd Bergmann /* TODO: stop DMA */ 278*0185f850SArnd Bergmann 279*0185f850SArnd Bergmann /* Release all active buffers */ 280*0185f850SArnd Bergmann return_all_buffers(skel, VB2_BUF_STATE_ERROR); 281*0185f850SArnd Bergmann } 282*0185f850SArnd Bergmann 283*0185f850SArnd Bergmann /* 284*0185f850SArnd Bergmann * The vb2 queue ops. Note that since q->lock is set we can use the standard 285*0185f850SArnd Bergmann * vb2_ops_wait_prepare/finish helper functions. If q->lock would be NULL, 286*0185f850SArnd Bergmann * then this driver would have to provide these ops. 287*0185f850SArnd Bergmann */ 288*0185f850SArnd Bergmann static struct vb2_ops skel_qops = { 289*0185f850SArnd Bergmann .queue_setup = queue_setup, 290*0185f850SArnd Bergmann .buf_prepare = buffer_prepare, 291*0185f850SArnd Bergmann .buf_queue = buffer_queue, 292*0185f850SArnd Bergmann .start_streaming = start_streaming, 293*0185f850SArnd Bergmann .stop_streaming = stop_streaming, 294*0185f850SArnd Bergmann .wait_prepare = vb2_ops_wait_prepare, 295*0185f850SArnd Bergmann .wait_finish = vb2_ops_wait_finish, 296*0185f850SArnd Bergmann }; 297*0185f850SArnd Bergmann 298*0185f850SArnd Bergmann /* 299*0185f850SArnd Bergmann * Required ioctl querycap. Note that the version field is prefilled with 300*0185f850SArnd Bergmann * the version of the kernel. 301*0185f850SArnd Bergmann */ 302*0185f850SArnd Bergmann static int skeleton_querycap(struct file *file, void *priv, 303*0185f850SArnd Bergmann struct v4l2_capability *cap) 304*0185f850SArnd Bergmann { 305*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 306*0185f850SArnd Bergmann 307*0185f850SArnd Bergmann strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); 308*0185f850SArnd Bergmann strlcpy(cap->card, "V4L2 PCI Skeleton", sizeof(cap->card)); 309*0185f850SArnd Bergmann snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", 310*0185f850SArnd Bergmann pci_name(skel->pdev)); 311*0185f850SArnd Bergmann return 0; 312*0185f850SArnd Bergmann } 313*0185f850SArnd Bergmann 314*0185f850SArnd Bergmann /* 315*0185f850SArnd Bergmann * Helper function to check and correct struct v4l2_pix_format. It's used 316*0185f850SArnd Bergmann * not only in VIDIOC_TRY/S_FMT, but also elsewhere if changes to the SDTV 317*0185f850SArnd Bergmann * standard, HDTV timings or the video input would require updating the 318*0185f850SArnd Bergmann * current format. 319*0185f850SArnd Bergmann */ 320*0185f850SArnd Bergmann static void skeleton_fill_pix_format(struct skeleton *skel, 321*0185f850SArnd Bergmann struct v4l2_pix_format *pix) 322*0185f850SArnd Bergmann { 323*0185f850SArnd Bergmann pix->pixelformat = V4L2_PIX_FMT_YUYV; 324*0185f850SArnd Bergmann if (skel->input == 0) { 325*0185f850SArnd Bergmann /* S-Video input */ 326*0185f850SArnd Bergmann pix->width = 720; 327*0185f850SArnd Bergmann pix->height = (skel->std & V4L2_STD_525_60) ? 480 : 576; 328*0185f850SArnd Bergmann pix->field = V4L2_FIELD_INTERLACED; 329*0185f850SArnd Bergmann pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 330*0185f850SArnd Bergmann } else { 331*0185f850SArnd Bergmann /* HDMI input */ 332*0185f850SArnd Bergmann pix->width = skel->timings.bt.width; 333*0185f850SArnd Bergmann pix->height = skel->timings.bt.height; 334*0185f850SArnd Bergmann if (skel->timings.bt.interlaced) { 335*0185f850SArnd Bergmann pix->field = V4L2_FIELD_ALTERNATE; 336*0185f850SArnd Bergmann pix->height /= 2; 337*0185f850SArnd Bergmann } else { 338*0185f850SArnd Bergmann pix->field = V4L2_FIELD_NONE; 339*0185f850SArnd Bergmann } 340*0185f850SArnd Bergmann pix->colorspace = V4L2_COLORSPACE_REC709; 341*0185f850SArnd Bergmann } 342*0185f850SArnd Bergmann 343*0185f850SArnd Bergmann /* 344*0185f850SArnd Bergmann * The YUYV format is four bytes for every two pixels, so bytesperline 345*0185f850SArnd Bergmann * is width * 2. 346*0185f850SArnd Bergmann */ 347*0185f850SArnd Bergmann pix->bytesperline = pix->width * 2; 348*0185f850SArnd Bergmann pix->sizeimage = pix->bytesperline * pix->height; 349*0185f850SArnd Bergmann pix->priv = 0; 350*0185f850SArnd Bergmann } 351*0185f850SArnd Bergmann 352*0185f850SArnd Bergmann static int skeleton_try_fmt_vid_cap(struct file *file, void *priv, 353*0185f850SArnd Bergmann struct v4l2_format *f) 354*0185f850SArnd Bergmann { 355*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 356*0185f850SArnd Bergmann struct v4l2_pix_format *pix = &f->fmt.pix; 357*0185f850SArnd Bergmann 358*0185f850SArnd Bergmann /* 359*0185f850SArnd Bergmann * Due to historical reasons providing try_fmt with an unsupported 360*0185f850SArnd Bergmann * pixelformat will return -EINVAL for video receivers. Webcam drivers, 361*0185f850SArnd Bergmann * however, will silently correct the pixelformat. Some video capture 362*0185f850SArnd Bergmann * applications rely on this behavior... 363*0185f850SArnd Bergmann */ 364*0185f850SArnd Bergmann if (pix->pixelformat != V4L2_PIX_FMT_YUYV) 365*0185f850SArnd Bergmann return -EINVAL; 366*0185f850SArnd Bergmann skeleton_fill_pix_format(skel, pix); 367*0185f850SArnd Bergmann return 0; 368*0185f850SArnd Bergmann } 369*0185f850SArnd Bergmann 370*0185f850SArnd Bergmann static int skeleton_s_fmt_vid_cap(struct file *file, void *priv, 371*0185f850SArnd Bergmann struct v4l2_format *f) 372*0185f850SArnd Bergmann { 373*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 374*0185f850SArnd Bergmann int ret; 375*0185f850SArnd Bergmann 376*0185f850SArnd Bergmann ret = skeleton_try_fmt_vid_cap(file, priv, f); 377*0185f850SArnd Bergmann if (ret) 378*0185f850SArnd Bergmann return ret; 379*0185f850SArnd Bergmann 380*0185f850SArnd Bergmann /* 381*0185f850SArnd Bergmann * It is not allowed to change the format while buffers for use with 382*0185f850SArnd Bergmann * streaming have already been allocated. 383*0185f850SArnd Bergmann */ 384*0185f850SArnd Bergmann if (vb2_is_busy(&skel->queue)) 385*0185f850SArnd Bergmann return -EBUSY; 386*0185f850SArnd Bergmann 387*0185f850SArnd Bergmann /* TODO: change format */ 388*0185f850SArnd Bergmann skel->format = f->fmt.pix; 389*0185f850SArnd Bergmann return 0; 390*0185f850SArnd Bergmann } 391*0185f850SArnd Bergmann 392*0185f850SArnd Bergmann static int skeleton_g_fmt_vid_cap(struct file *file, void *priv, 393*0185f850SArnd Bergmann struct v4l2_format *f) 394*0185f850SArnd Bergmann { 395*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 396*0185f850SArnd Bergmann 397*0185f850SArnd Bergmann f->fmt.pix = skel->format; 398*0185f850SArnd Bergmann return 0; 399*0185f850SArnd Bergmann } 400*0185f850SArnd Bergmann 401*0185f850SArnd Bergmann static int skeleton_enum_fmt_vid_cap(struct file *file, void *priv, 402*0185f850SArnd Bergmann struct v4l2_fmtdesc *f) 403*0185f850SArnd Bergmann { 404*0185f850SArnd Bergmann if (f->index != 0) 405*0185f850SArnd Bergmann return -EINVAL; 406*0185f850SArnd Bergmann 407*0185f850SArnd Bergmann f->pixelformat = V4L2_PIX_FMT_YUYV; 408*0185f850SArnd Bergmann return 0; 409*0185f850SArnd Bergmann } 410*0185f850SArnd Bergmann 411*0185f850SArnd Bergmann static int skeleton_s_std(struct file *file, void *priv, v4l2_std_id std) 412*0185f850SArnd Bergmann { 413*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 414*0185f850SArnd Bergmann 415*0185f850SArnd Bergmann /* S_STD is not supported on the HDMI input */ 416*0185f850SArnd Bergmann if (skel->input) 417*0185f850SArnd Bergmann return -ENODATA; 418*0185f850SArnd Bergmann 419*0185f850SArnd Bergmann /* 420*0185f850SArnd Bergmann * No change, so just return. Some applications call S_STD again after 421*0185f850SArnd Bergmann * the buffers for streaming have been set up, so we have to allow for 422*0185f850SArnd Bergmann * this behavior. 423*0185f850SArnd Bergmann */ 424*0185f850SArnd Bergmann if (std == skel->std) 425*0185f850SArnd Bergmann return 0; 426*0185f850SArnd Bergmann 427*0185f850SArnd Bergmann /* 428*0185f850SArnd Bergmann * Changing the standard implies a format change, which is not allowed 429*0185f850SArnd Bergmann * while buffers for use with streaming have already been allocated. 430*0185f850SArnd Bergmann */ 431*0185f850SArnd Bergmann if (vb2_is_busy(&skel->queue)) 432*0185f850SArnd Bergmann return -EBUSY; 433*0185f850SArnd Bergmann 434*0185f850SArnd Bergmann /* TODO: handle changing std */ 435*0185f850SArnd Bergmann 436*0185f850SArnd Bergmann skel->std = std; 437*0185f850SArnd Bergmann 438*0185f850SArnd Bergmann /* Update the internal format */ 439*0185f850SArnd Bergmann skeleton_fill_pix_format(skel, &skel->format); 440*0185f850SArnd Bergmann return 0; 441*0185f850SArnd Bergmann } 442*0185f850SArnd Bergmann 443*0185f850SArnd Bergmann static int skeleton_g_std(struct file *file, void *priv, v4l2_std_id *std) 444*0185f850SArnd Bergmann { 445*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 446*0185f850SArnd Bergmann 447*0185f850SArnd Bergmann /* G_STD is not supported on the HDMI input */ 448*0185f850SArnd Bergmann if (skel->input) 449*0185f850SArnd Bergmann return -ENODATA; 450*0185f850SArnd Bergmann 451*0185f850SArnd Bergmann *std = skel->std; 452*0185f850SArnd Bergmann return 0; 453*0185f850SArnd Bergmann } 454*0185f850SArnd Bergmann 455*0185f850SArnd Bergmann /* 456*0185f850SArnd Bergmann * Query the current standard as seen by the hardware. This function shall 457*0185f850SArnd Bergmann * never actually change the standard, it just detects and reports. 458*0185f850SArnd Bergmann * The framework will initially set *std to tvnorms (i.e. the set of 459*0185f850SArnd Bergmann * supported standards by this input), and this function should just AND 460*0185f850SArnd Bergmann * this value. If there is no signal, then *std should be set to 0. 461*0185f850SArnd Bergmann */ 462*0185f850SArnd Bergmann static int skeleton_querystd(struct file *file, void *priv, v4l2_std_id *std) 463*0185f850SArnd Bergmann { 464*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 465*0185f850SArnd Bergmann 466*0185f850SArnd Bergmann /* QUERY_STD is not supported on the HDMI input */ 467*0185f850SArnd Bergmann if (skel->input) 468*0185f850SArnd Bergmann return -ENODATA; 469*0185f850SArnd Bergmann 470*0185f850SArnd Bergmann #ifdef TODO 471*0185f850SArnd Bergmann /* 472*0185f850SArnd Bergmann * Query currently seen standard. Initial value of *std is 473*0185f850SArnd Bergmann * V4L2_STD_ALL. This function should look something like this: 474*0185f850SArnd Bergmann */ 475*0185f850SArnd Bergmann get_signal_info(); 476*0185f850SArnd Bergmann if (no_signal) { 477*0185f850SArnd Bergmann *std = 0; 478*0185f850SArnd Bergmann return 0; 479*0185f850SArnd Bergmann } 480*0185f850SArnd Bergmann /* Use signal information to reduce the number of possible standards */ 481*0185f850SArnd Bergmann if (signal_has_525_lines) 482*0185f850SArnd Bergmann *std &= V4L2_STD_525_60; 483*0185f850SArnd Bergmann else 484*0185f850SArnd Bergmann *std &= V4L2_STD_625_50; 485*0185f850SArnd Bergmann #endif 486*0185f850SArnd Bergmann return 0; 487*0185f850SArnd Bergmann } 488*0185f850SArnd Bergmann 489*0185f850SArnd Bergmann static int skeleton_s_dv_timings(struct file *file, void *_fh, 490*0185f850SArnd Bergmann struct v4l2_dv_timings *timings) 491*0185f850SArnd Bergmann { 492*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 493*0185f850SArnd Bergmann 494*0185f850SArnd Bergmann /* S_DV_TIMINGS is not supported on the S-Video input */ 495*0185f850SArnd Bergmann if (skel->input == 0) 496*0185f850SArnd Bergmann return -ENODATA; 497*0185f850SArnd Bergmann 498*0185f850SArnd Bergmann /* Quick sanity check */ 499*0185f850SArnd Bergmann if (!v4l2_valid_dv_timings(timings, &skel_timings_cap, NULL, NULL)) 500*0185f850SArnd Bergmann return -EINVAL; 501*0185f850SArnd Bergmann 502*0185f850SArnd Bergmann /* Check if the timings are part of the CEA-861 timings. */ 503*0185f850SArnd Bergmann if (!v4l2_find_dv_timings_cap(timings, &skel_timings_cap, 504*0185f850SArnd Bergmann 0, NULL, NULL)) 505*0185f850SArnd Bergmann return -EINVAL; 506*0185f850SArnd Bergmann 507*0185f850SArnd Bergmann /* Return 0 if the new timings are the same as the current timings. */ 508*0185f850SArnd Bergmann if (v4l2_match_dv_timings(timings, &skel->timings, 0, false)) 509*0185f850SArnd Bergmann return 0; 510*0185f850SArnd Bergmann 511*0185f850SArnd Bergmann /* 512*0185f850SArnd Bergmann * Changing the timings implies a format change, which is not allowed 513*0185f850SArnd Bergmann * while buffers for use with streaming have already been allocated. 514*0185f850SArnd Bergmann */ 515*0185f850SArnd Bergmann if (vb2_is_busy(&skel->queue)) 516*0185f850SArnd Bergmann return -EBUSY; 517*0185f850SArnd Bergmann 518*0185f850SArnd Bergmann /* TODO: Configure new timings */ 519*0185f850SArnd Bergmann 520*0185f850SArnd Bergmann /* Save timings */ 521*0185f850SArnd Bergmann skel->timings = *timings; 522*0185f850SArnd Bergmann 523*0185f850SArnd Bergmann /* Update the internal format */ 524*0185f850SArnd Bergmann skeleton_fill_pix_format(skel, &skel->format); 525*0185f850SArnd Bergmann return 0; 526*0185f850SArnd Bergmann } 527*0185f850SArnd Bergmann 528*0185f850SArnd Bergmann static int skeleton_g_dv_timings(struct file *file, void *_fh, 529*0185f850SArnd Bergmann struct v4l2_dv_timings *timings) 530*0185f850SArnd Bergmann { 531*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 532*0185f850SArnd Bergmann 533*0185f850SArnd Bergmann /* G_DV_TIMINGS is not supported on the S-Video input */ 534*0185f850SArnd Bergmann if (skel->input == 0) 535*0185f850SArnd Bergmann return -ENODATA; 536*0185f850SArnd Bergmann 537*0185f850SArnd Bergmann *timings = skel->timings; 538*0185f850SArnd Bergmann return 0; 539*0185f850SArnd Bergmann } 540*0185f850SArnd Bergmann 541*0185f850SArnd Bergmann static int skeleton_enum_dv_timings(struct file *file, void *_fh, 542*0185f850SArnd Bergmann struct v4l2_enum_dv_timings *timings) 543*0185f850SArnd Bergmann { 544*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 545*0185f850SArnd Bergmann 546*0185f850SArnd Bergmann /* ENUM_DV_TIMINGS is not supported on the S-Video input */ 547*0185f850SArnd Bergmann if (skel->input == 0) 548*0185f850SArnd Bergmann return -ENODATA; 549*0185f850SArnd Bergmann 550*0185f850SArnd Bergmann return v4l2_enum_dv_timings_cap(timings, &skel_timings_cap, 551*0185f850SArnd Bergmann NULL, NULL); 552*0185f850SArnd Bergmann } 553*0185f850SArnd Bergmann 554*0185f850SArnd Bergmann /* 555*0185f850SArnd Bergmann * Query the current timings as seen by the hardware. This function shall 556*0185f850SArnd Bergmann * never actually change the timings, it just detects and reports. 557*0185f850SArnd Bergmann * If no signal is detected, then return -ENOLINK. If the hardware cannot 558*0185f850SArnd Bergmann * lock to the signal, then return -ENOLCK. If the signal is out of range 559*0185f850SArnd Bergmann * of the capabilities of the system (e.g., it is possible that the receiver 560*0185f850SArnd Bergmann * can lock but that the DMA engine it is connected to cannot handle 561*0185f850SArnd Bergmann * pixelclocks above a certain frequency), then -ERANGE is returned. 562*0185f850SArnd Bergmann */ 563*0185f850SArnd Bergmann static int skeleton_query_dv_timings(struct file *file, void *_fh, 564*0185f850SArnd Bergmann struct v4l2_dv_timings *timings) 565*0185f850SArnd Bergmann { 566*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 567*0185f850SArnd Bergmann 568*0185f850SArnd Bergmann /* QUERY_DV_TIMINGS is not supported on the S-Video input */ 569*0185f850SArnd Bergmann if (skel->input == 0) 570*0185f850SArnd Bergmann return -ENODATA; 571*0185f850SArnd Bergmann 572*0185f850SArnd Bergmann #ifdef TODO 573*0185f850SArnd Bergmann /* 574*0185f850SArnd Bergmann * Query currently seen timings. This function should look 575*0185f850SArnd Bergmann * something like this: 576*0185f850SArnd Bergmann */ 577*0185f850SArnd Bergmann detect_timings(); 578*0185f850SArnd Bergmann if (no_signal) 579*0185f850SArnd Bergmann return -ENOLINK; 580*0185f850SArnd Bergmann if (cannot_lock_to_signal) 581*0185f850SArnd Bergmann return -ENOLCK; 582*0185f850SArnd Bergmann if (signal_out_of_range_of_capabilities) 583*0185f850SArnd Bergmann return -ERANGE; 584*0185f850SArnd Bergmann 585*0185f850SArnd Bergmann /* Useful for debugging */ 586*0185f850SArnd Bergmann v4l2_print_dv_timings(skel->v4l2_dev.name, "query_dv_timings:", 587*0185f850SArnd Bergmann timings, true); 588*0185f850SArnd Bergmann #endif 589*0185f850SArnd Bergmann return 0; 590*0185f850SArnd Bergmann } 591*0185f850SArnd Bergmann 592*0185f850SArnd Bergmann static int skeleton_dv_timings_cap(struct file *file, void *fh, 593*0185f850SArnd Bergmann struct v4l2_dv_timings_cap *cap) 594*0185f850SArnd Bergmann { 595*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 596*0185f850SArnd Bergmann 597*0185f850SArnd Bergmann /* DV_TIMINGS_CAP is not supported on the S-Video input */ 598*0185f850SArnd Bergmann if (skel->input == 0) 599*0185f850SArnd Bergmann return -ENODATA; 600*0185f850SArnd Bergmann *cap = skel_timings_cap; 601*0185f850SArnd Bergmann return 0; 602*0185f850SArnd Bergmann } 603*0185f850SArnd Bergmann 604*0185f850SArnd Bergmann static int skeleton_enum_input(struct file *file, void *priv, 605*0185f850SArnd Bergmann struct v4l2_input *i) 606*0185f850SArnd Bergmann { 607*0185f850SArnd Bergmann if (i->index > 1) 608*0185f850SArnd Bergmann return -EINVAL; 609*0185f850SArnd Bergmann 610*0185f850SArnd Bergmann i->type = V4L2_INPUT_TYPE_CAMERA; 611*0185f850SArnd Bergmann if (i->index == 0) { 612*0185f850SArnd Bergmann i->std = SKEL_TVNORMS; 613*0185f850SArnd Bergmann strlcpy(i->name, "S-Video", sizeof(i->name)); 614*0185f850SArnd Bergmann i->capabilities = V4L2_IN_CAP_STD; 615*0185f850SArnd Bergmann } else { 616*0185f850SArnd Bergmann i->std = 0; 617*0185f850SArnd Bergmann strlcpy(i->name, "HDMI", sizeof(i->name)); 618*0185f850SArnd Bergmann i->capabilities = V4L2_IN_CAP_DV_TIMINGS; 619*0185f850SArnd Bergmann } 620*0185f850SArnd Bergmann return 0; 621*0185f850SArnd Bergmann } 622*0185f850SArnd Bergmann 623*0185f850SArnd Bergmann static int skeleton_s_input(struct file *file, void *priv, unsigned int i) 624*0185f850SArnd Bergmann { 625*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 626*0185f850SArnd Bergmann 627*0185f850SArnd Bergmann if (i > 1) 628*0185f850SArnd Bergmann return -EINVAL; 629*0185f850SArnd Bergmann 630*0185f850SArnd Bergmann /* 631*0185f850SArnd Bergmann * Changing the input implies a format change, which is not allowed 632*0185f850SArnd Bergmann * while buffers for use with streaming have already been allocated. 633*0185f850SArnd Bergmann */ 634*0185f850SArnd Bergmann if (vb2_is_busy(&skel->queue)) 635*0185f850SArnd Bergmann return -EBUSY; 636*0185f850SArnd Bergmann 637*0185f850SArnd Bergmann skel->input = i; 638*0185f850SArnd Bergmann /* 639*0185f850SArnd Bergmann * Update tvnorms. The tvnorms value is used by the core to implement 640*0185f850SArnd Bergmann * VIDIOC_ENUMSTD so it has to be correct. If tvnorms == 0, then 641*0185f850SArnd Bergmann * ENUMSTD will return -ENODATA. 642*0185f850SArnd Bergmann */ 643*0185f850SArnd Bergmann skel->vdev.tvnorms = i ? 0 : SKEL_TVNORMS; 644*0185f850SArnd Bergmann 645*0185f850SArnd Bergmann /* Update the internal format */ 646*0185f850SArnd Bergmann skeleton_fill_pix_format(skel, &skel->format); 647*0185f850SArnd Bergmann return 0; 648*0185f850SArnd Bergmann } 649*0185f850SArnd Bergmann 650*0185f850SArnd Bergmann static int skeleton_g_input(struct file *file, void *priv, unsigned int *i) 651*0185f850SArnd Bergmann { 652*0185f850SArnd Bergmann struct skeleton *skel = video_drvdata(file); 653*0185f850SArnd Bergmann 654*0185f850SArnd Bergmann *i = skel->input; 655*0185f850SArnd Bergmann return 0; 656*0185f850SArnd Bergmann } 657*0185f850SArnd Bergmann 658*0185f850SArnd Bergmann /* The control handler. */ 659*0185f850SArnd Bergmann static int skeleton_s_ctrl(struct v4l2_ctrl *ctrl) 660*0185f850SArnd Bergmann { 661*0185f850SArnd Bergmann /*struct skeleton *skel = 662*0185f850SArnd Bergmann container_of(ctrl->handler, struct skeleton, ctrl_handler);*/ 663*0185f850SArnd Bergmann 664*0185f850SArnd Bergmann switch (ctrl->id) { 665*0185f850SArnd Bergmann case V4L2_CID_BRIGHTNESS: 666*0185f850SArnd Bergmann /* TODO: set brightness to ctrl->val */ 667*0185f850SArnd Bergmann break; 668*0185f850SArnd Bergmann case V4L2_CID_CONTRAST: 669*0185f850SArnd Bergmann /* TODO: set contrast to ctrl->val */ 670*0185f850SArnd Bergmann break; 671*0185f850SArnd Bergmann case V4L2_CID_SATURATION: 672*0185f850SArnd Bergmann /* TODO: set saturation to ctrl->val */ 673*0185f850SArnd Bergmann break; 674*0185f850SArnd Bergmann case V4L2_CID_HUE: 675*0185f850SArnd Bergmann /* TODO: set hue to ctrl->val */ 676*0185f850SArnd Bergmann break; 677*0185f850SArnd Bergmann default: 678*0185f850SArnd Bergmann return -EINVAL; 679*0185f850SArnd Bergmann } 680*0185f850SArnd Bergmann return 0; 681*0185f850SArnd Bergmann } 682*0185f850SArnd Bergmann 683*0185f850SArnd Bergmann /* ------------------------------------------------------------------ 684*0185f850SArnd Bergmann File operations for the device 685*0185f850SArnd Bergmann ------------------------------------------------------------------*/ 686*0185f850SArnd Bergmann 687*0185f850SArnd Bergmann static const struct v4l2_ctrl_ops skel_ctrl_ops = { 688*0185f850SArnd Bergmann .s_ctrl = skeleton_s_ctrl, 689*0185f850SArnd Bergmann }; 690*0185f850SArnd Bergmann 691*0185f850SArnd Bergmann /* 692*0185f850SArnd Bergmann * The set of all supported ioctls. Note that all the streaming ioctls 693*0185f850SArnd Bergmann * use the vb2 helper functions that take care of all the locking and 694*0185f850SArnd Bergmann * that also do ownership tracking (i.e. only the filehandle that requested 695*0185f850SArnd Bergmann * the buffers can call the streaming ioctls, all other filehandles will 696*0185f850SArnd Bergmann * receive -EBUSY if they attempt to call the same streaming ioctls). 697*0185f850SArnd Bergmann * 698*0185f850SArnd Bergmann * The last three ioctls also use standard helper functions: these implement 699*0185f850SArnd Bergmann * standard behavior for drivers with controls. 700*0185f850SArnd Bergmann */ 701*0185f850SArnd Bergmann static const struct v4l2_ioctl_ops skel_ioctl_ops = { 702*0185f850SArnd Bergmann .vidioc_querycap = skeleton_querycap, 703*0185f850SArnd Bergmann .vidioc_try_fmt_vid_cap = skeleton_try_fmt_vid_cap, 704*0185f850SArnd Bergmann .vidioc_s_fmt_vid_cap = skeleton_s_fmt_vid_cap, 705*0185f850SArnd Bergmann .vidioc_g_fmt_vid_cap = skeleton_g_fmt_vid_cap, 706*0185f850SArnd Bergmann .vidioc_enum_fmt_vid_cap = skeleton_enum_fmt_vid_cap, 707*0185f850SArnd Bergmann 708*0185f850SArnd Bergmann .vidioc_g_std = skeleton_g_std, 709*0185f850SArnd Bergmann .vidioc_s_std = skeleton_s_std, 710*0185f850SArnd Bergmann .vidioc_querystd = skeleton_querystd, 711*0185f850SArnd Bergmann 712*0185f850SArnd Bergmann .vidioc_s_dv_timings = skeleton_s_dv_timings, 713*0185f850SArnd Bergmann .vidioc_g_dv_timings = skeleton_g_dv_timings, 714*0185f850SArnd Bergmann .vidioc_enum_dv_timings = skeleton_enum_dv_timings, 715*0185f850SArnd Bergmann .vidioc_query_dv_timings = skeleton_query_dv_timings, 716*0185f850SArnd Bergmann .vidioc_dv_timings_cap = skeleton_dv_timings_cap, 717*0185f850SArnd Bergmann 718*0185f850SArnd Bergmann .vidioc_enum_input = skeleton_enum_input, 719*0185f850SArnd Bergmann .vidioc_g_input = skeleton_g_input, 720*0185f850SArnd Bergmann .vidioc_s_input = skeleton_s_input, 721*0185f850SArnd Bergmann 722*0185f850SArnd Bergmann .vidioc_reqbufs = vb2_ioctl_reqbufs, 723*0185f850SArnd Bergmann .vidioc_create_bufs = vb2_ioctl_create_bufs, 724*0185f850SArnd Bergmann .vidioc_querybuf = vb2_ioctl_querybuf, 725*0185f850SArnd Bergmann .vidioc_qbuf = vb2_ioctl_qbuf, 726*0185f850SArnd Bergmann .vidioc_dqbuf = vb2_ioctl_dqbuf, 727*0185f850SArnd Bergmann .vidioc_expbuf = vb2_ioctl_expbuf, 728*0185f850SArnd Bergmann .vidioc_streamon = vb2_ioctl_streamon, 729*0185f850SArnd Bergmann .vidioc_streamoff = vb2_ioctl_streamoff, 730*0185f850SArnd Bergmann 731*0185f850SArnd Bergmann .vidioc_log_status = v4l2_ctrl_log_status, 732*0185f850SArnd Bergmann .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 733*0185f850SArnd Bergmann .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 734*0185f850SArnd Bergmann }; 735*0185f850SArnd Bergmann 736*0185f850SArnd Bergmann /* 737*0185f850SArnd Bergmann * The set of file operations. Note that all these ops are standard core 738*0185f850SArnd Bergmann * helper functions. 739*0185f850SArnd Bergmann */ 740*0185f850SArnd Bergmann static const struct v4l2_file_operations skel_fops = { 741*0185f850SArnd Bergmann .owner = THIS_MODULE, 742*0185f850SArnd Bergmann .open = v4l2_fh_open, 743*0185f850SArnd Bergmann .release = vb2_fop_release, 744*0185f850SArnd Bergmann .unlocked_ioctl = video_ioctl2, 745*0185f850SArnd Bergmann .read = vb2_fop_read, 746*0185f850SArnd Bergmann .mmap = vb2_fop_mmap, 747*0185f850SArnd Bergmann .poll = vb2_fop_poll, 748*0185f850SArnd Bergmann }; 749*0185f850SArnd Bergmann 750*0185f850SArnd Bergmann /* 751*0185f850SArnd Bergmann * The initial setup of this device instance. Note that the initial state of 752*0185f850SArnd Bergmann * the driver should be complete. So the initial format, standard, timings 753*0185f850SArnd Bergmann * and video input should all be initialized to some reasonable value. 754*0185f850SArnd Bergmann */ 755*0185f850SArnd Bergmann static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 756*0185f850SArnd Bergmann { 757*0185f850SArnd Bergmann /* The initial timings are chosen to be 720p60. */ 758*0185f850SArnd Bergmann static const struct v4l2_dv_timings timings_def = 759*0185f850SArnd Bergmann V4L2_DV_BT_CEA_1280X720P60; 760*0185f850SArnd Bergmann struct skeleton *skel; 761*0185f850SArnd Bergmann struct video_device *vdev; 762*0185f850SArnd Bergmann struct v4l2_ctrl_handler *hdl; 763*0185f850SArnd Bergmann struct vb2_queue *q; 764*0185f850SArnd Bergmann int ret; 765*0185f850SArnd Bergmann 766*0185f850SArnd Bergmann /* Enable PCI */ 767*0185f850SArnd Bergmann ret = pci_enable_device(pdev); 768*0185f850SArnd Bergmann if (ret) 769*0185f850SArnd Bergmann return ret; 770*0185f850SArnd Bergmann ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 771*0185f850SArnd Bergmann if (ret) { 772*0185f850SArnd Bergmann dev_err(&pdev->dev, "no suitable DMA available.\n"); 773*0185f850SArnd Bergmann goto disable_pci; 774*0185f850SArnd Bergmann } 775*0185f850SArnd Bergmann 776*0185f850SArnd Bergmann /* Allocate a new instance */ 777*0185f850SArnd Bergmann skel = devm_kzalloc(&pdev->dev, sizeof(struct skeleton), GFP_KERNEL); 778*0185f850SArnd Bergmann if (!skel) 779*0185f850SArnd Bergmann return -ENOMEM; 780*0185f850SArnd Bergmann 781*0185f850SArnd Bergmann /* Allocate the interrupt */ 782*0185f850SArnd Bergmann ret = devm_request_irq(&pdev->dev, pdev->irq, 783*0185f850SArnd Bergmann skeleton_irq, 0, KBUILD_MODNAME, skel); 784*0185f850SArnd Bergmann if (ret) { 785*0185f850SArnd Bergmann dev_err(&pdev->dev, "request_irq failed\n"); 786*0185f850SArnd Bergmann goto disable_pci; 787*0185f850SArnd Bergmann } 788*0185f850SArnd Bergmann skel->pdev = pdev; 789*0185f850SArnd Bergmann 790*0185f850SArnd Bergmann /* Fill in the initial format-related settings */ 791*0185f850SArnd Bergmann skel->timings = timings_def; 792*0185f850SArnd Bergmann skel->std = V4L2_STD_625_50; 793*0185f850SArnd Bergmann skeleton_fill_pix_format(skel, &skel->format); 794*0185f850SArnd Bergmann 795*0185f850SArnd Bergmann /* Initialize the top-level structure */ 796*0185f850SArnd Bergmann ret = v4l2_device_register(&pdev->dev, &skel->v4l2_dev); 797*0185f850SArnd Bergmann if (ret) 798*0185f850SArnd Bergmann goto disable_pci; 799*0185f850SArnd Bergmann 800*0185f850SArnd Bergmann mutex_init(&skel->lock); 801*0185f850SArnd Bergmann 802*0185f850SArnd Bergmann /* Add the controls */ 803*0185f850SArnd Bergmann hdl = &skel->ctrl_handler; 804*0185f850SArnd Bergmann v4l2_ctrl_handler_init(hdl, 4); 805*0185f850SArnd Bergmann v4l2_ctrl_new_std(hdl, &skel_ctrl_ops, 806*0185f850SArnd Bergmann V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); 807*0185f850SArnd Bergmann v4l2_ctrl_new_std(hdl, &skel_ctrl_ops, 808*0185f850SArnd Bergmann V4L2_CID_CONTRAST, 0, 255, 1, 16); 809*0185f850SArnd Bergmann v4l2_ctrl_new_std(hdl, &skel_ctrl_ops, 810*0185f850SArnd Bergmann V4L2_CID_SATURATION, 0, 255, 1, 127); 811*0185f850SArnd Bergmann v4l2_ctrl_new_std(hdl, &skel_ctrl_ops, 812*0185f850SArnd Bergmann V4L2_CID_HUE, -128, 127, 1, 0); 813*0185f850SArnd Bergmann if (hdl->error) { 814*0185f850SArnd Bergmann ret = hdl->error; 815*0185f850SArnd Bergmann goto free_hdl; 816*0185f850SArnd Bergmann } 817*0185f850SArnd Bergmann skel->v4l2_dev.ctrl_handler = hdl; 818*0185f850SArnd Bergmann 819*0185f850SArnd Bergmann /* Initialize the vb2 queue */ 820*0185f850SArnd Bergmann q = &skel->queue; 821*0185f850SArnd Bergmann q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 822*0185f850SArnd Bergmann q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; 823*0185f850SArnd Bergmann q->drv_priv = skel; 824*0185f850SArnd Bergmann q->buf_struct_size = sizeof(struct skel_buffer); 825*0185f850SArnd Bergmann q->ops = &skel_qops; 826*0185f850SArnd Bergmann q->mem_ops = &vb2_dma_contig_memops; 827*0185f850SArnd Bergmann q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 828*0185f850SArnd Bergmann /* 829*0185f850SArnd Bergmann * Assume that this DMA engine needs to have at least two buffers 830*0185f850SArnd Bergmann * available before it can be started. The start_streaming() op 831*0185f850SArnd Bergmann * won't be called until at least this many buffers are queued up. 832*0185f850SArnd Bergmann */ 833*0185f850SArnd Bergmann q->min_buffers_needed = 2; 834*0185f850SArnd Bergmann /* 835*0185f850SArnd Bergmann * The serialization lock for the streaming ioctls. This is the same 836*0185f850SArnd Bergmann * as the main serialization lock, but if some of the non-streaming 837*0185f850SArnd Bergmann * ioctls could take a long time to execute, then you might want to 838*0185f850SArnd Bergmann * have a different lock here to prevent VIDIOC_DQBUF from being 839*0185f850SArnd Bergmann * blocked while waiting for another action to finish. This is 840*0185f850SArnd Bergmann * generally not needed for PCI devices, but USB devices usually do 841*0185f850SArnd Bergmann * want a separate lock here. 842*0185f850SArnd Bergmann */ 843*0185f850SArnd Bergmann q->lock = &skel->lock; 844*0185f850SArnd Bergmann /* 845*0185f850SArnd Bergmann * Since this driver can only do 32-bit DMA we must make sure that 846*0185f850SArnd Bergmann * the vb2 core will allocate the buffers in 32-bit DMA memory. 847*0185f850SArnd Bergmann */ 848*0185f850SArnd Bergmann q->gfp_flags = GFP_DMA32; 849*0185f850SArnd Bergmann ret = vb2_queue_init(q); 850*0185f850SArnd Bergmann if (ret) 851*0185f850SArnd Bergmann goto free_hdl; 852*0185f850SArnd Bergmann 853*0185f850SArnd Bergmann skel->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 854*0185f850SArnd Bergmann if (IS_ERR(skel->alloc_ctx)) { 855*0185f850SArnd Bergmann dev_err(&pdev->dev, "Can't allocate buffer context"); 856*0185f850SArnd Bergmann ret = PTR_ERR(skel->alloc_ctx); 857*0185f850SArnd Bergmann goto free_hdl; 858*0185f850SArnd Bergmann } 859*0185f850SArnd Bergmann INIT_LIST_HEAD(&skel->buf_list); 860*0185f850SArnd Bergmann spin_lock_init(&skel->qlock); 861*0185f850SArnd Bergmann 862*0185f850SArnd Bergmann /* Initialize the video_device structure */ 863*0185f850SArnd Bergmann vdev = &skel->vdev; 864*0185f850SArnd Bergmann strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name)); 865*0185f850SArnd Bergmann /* 866*0185f850SArnd Bergmann * There is nothing to clean up, so release is set to an empty release 867*0185f850SArnd Bergmann * function. The release callback must be non-NULL. 868*0185f850SArnd Bergmann */ 869*0185f850SArnd Bergmann vdev->release = video_device_release_empty; 870*0185f850SArnd Bergmann vdev->fops = &skel_fops, 871*0185f850SArnd Bergmann vdev->ioctl_ops = &skel_ioctl_ops, 872*0185f850SArnd Bergmann vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | 873*0185f850SArnd Bergmann V4L2_CAP_STREAMING; 874*0185f850SArnd Bergmann /* 875*0185f850SArnd Bergmann * The main serialization lock. All ioctls are serialized by this 876*0185f850SArnd Bergmann * lock. Exception: if q->lock is set, then the streaming ioctls 877*0185f850SArnd Bergmann * are serialized by that separate lock. 878*0185f850SArnd Bergmann */ 879*0185f850SArnd Bergmann vdev->lock = &skel->lock; 880*0185f850SArnd Bergmann vdev->queue = q; 881*0185f850SArnd Bergmann vdev->v4l2_dev = &skel->v4l2_dev; 882*0185f850SArnd Bergmann /* Supported SDTV standards, if any */ 883*0185f850SArnd Bergmann vdev->tvnorms = SKEL_TVNORMS; 884*0185f850SArnd Bergmann video_set_drvdata(vdev, skel); 885*0185f850SArnd Bergmann 886*0185f850SArnd Bergmann ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); 887*0185f850SArnd Bergmann if (ret) 888*0185f850SArnd Bergmann goto free_ctx; 889*0185f850SArnd Bergmann 890*0185f850SArnd Bergmann dev_info(&pdev->dev, "V4L2 PCI Skeleton Driver loaded\n"); 891*0185f850SArnd Bergmann return 0; 892*0185f850SArnd Bergmann 893*0185f850SArnd Bergmann free_ctx: 894*0185f850SArnd Bergmann vb2_dma_contig_cleanup_ctx(skel->alloc_ctx); 895*0185f850SArnd Bergmann free_hdl: 896*0185f850SArnd Bergmann v4l2_ctrl_handler_free(&skel->ctrl_handler); 897*0185f850SArnd Bergmann v4l2_device_unregister(&skel->v4l2_dev); 898*0185f850SArnd Bergmann disable_pci: 899*0185f850SArnd Bergmann pci_disable_device(pdev); 900*0185f850SArnd Bergmann return ret; 901*0185f850SArnd Bergmann } 902*0185f850SArnd Bergmann 903*0185f850SArnd Bergmann static void skeleton_remove(struct pci_dev *pdev) 904*0185f850SArnd Bergmann { 905*0185f850SArnd Bergmann struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); 906*0185f850SArnd Bergmann struct skeleton *skel = container_of(v4l2_dev, struct skeleton, v4l2_dev); 907*0185f850SArnd Bergmann 908*0185f850SArnd Bergmann video_unregister_device(&skel->vdev); 909*0185f850SArnd Bergmann v4l2_ctrl_handler_free(&skel->ctrl_handler); 910*0185f850SArnd Bergmann vb2_dma_contig_cleanup_ctx(skel->alloc_ctx); 911*0185f850SArnd Bergmann v4l2_device_unregister(&skel->v4l2_dev); 912*0185f850SArnd Bergmann pci_disable_device(skel->pdev); 913*0185f850SArnd Bergmann } 914*0185f850SArnd Bergmann 915*0185f850SArnd Bergmann static struct pci_driver skeleton_driver = { 916*0185f850SArnd Bergmann .name = KBUILD_MODNAME, 917*0185f850SArnd Bergmann .probe = skeleton_probe, 918*0185f850SArnd Bergmann .remove = skeleton_remove, 919*0185f850SArnd Bergmann .id_table = skeleton_pci_tbl, 920*0185f850SArnd Bergmann }; 921*0185f850SArnd Bergmann 922*0185f850SArnd Bergmann module_pci_driver(skeleton_driver); 923