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