1 /***************************************************************************
2 * Copyright (C) 2006-2010 by Marin Mitov *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 ***************************************************************************/
17 #include <linux/module.h>
18 #include <linux/stringify.h>
19 #include <linux/delay.h>
20 #include <linux/kthread.h>
21 #include <linux/slab.h>
22 #include <media/v4l2-dev.h>
23 #include <media/v4l2-ioctl.h>
24 #include <media/v4l2-common.h>
25 #include <media/videobuf2-dma-contig.h>
29 #define DT3155_DEVICE_ID 0x1223
32 * read_i2c_reg - reads an internal i2c register
34 * @addr: dt3155 mmio base address
35 * @index: index (internal address) of register to read
36 * @data: pointer to byte the read data will be placed in
38 * returns: zero on success or error code
40 * This function starts reading the specified (by index) register
41 * and busy waits for the process to finish. The result is placed
42 * in a byte pointed by data.
44 static int read_i2c_reg(void __iomem
*addr
, u8 index
, u8
*data
)
48 iowrite32((tmp
<< 17) | IIC_READ
, addr
+ IIC_CSR2
);
50 udelay(45); /* wait at least 43 usec for NEW_CYCLE to clear */
51 if (ioread32(addr
+ IIC_CSR2
) & NEW_CYCLE
)
52 return -EIO
; /* error: NEW_CYCLE not cleared */
53 tmp
= ioread32(addr
+ IIC_CSR1
);
54 if (tmp
& DIRECT_ABORT
) {
55 /* reset DIRECT_ABORT bit */
56 iowrite32(DIRECT_ABORT
, addr
+ IIC_CSR1
);
57 return -EIO
; /* error: DIRECT_ABORT set */
64 * write_i2c_reg - writes to an internal i2c register
66 * @addr: dt3155 mmio base address
67 * @index: index (internal address) of register to read
68 * @data: data to be written
70 * returns: zero on success or error code
72 * This function starts writing the specified (by index) register
73 * and busy waits for the process to finish.
75 static int write_i2c_reg(void __iomem
*addr
, u8 index
, u8 data
)
79 iowrite32((tmp
<< 17) | IIC_WRITE
| data
, addr
+ IIC_CSR2
);
81 udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */
82 if (ioread32(addr
+ IIC_CSR2
) & NEW_CYCLE
)
83 return -EIO
; /* error: NEW_CYCLE not cleared */
84 if (ioread32(addr
+ IIC_CSR1
) & DIRECT_ABORT
) {
85 /* reset DIRECT_ABORT bit */
86 iowrite32(DIRECT_ABORT
, addr
+ IIC_CSR1
);
87 return -EIO
; /* error: DIRECT_ABORT set */
93 * write_i2c_reg_nowait - writes to an internal i2c register
95 * @addr: dt3155 mmio base address
96 * @index: index (internal address) of register to read
97 * @data: data to be written
99 * This function starts writing the specified (by index) register
102 static void write_i2c_reg_nowait(void __iomem
*addr
, u8 index
, u8 data
)
106 iowrite32((tmp
<< 17) | IIC_WRITE
| data
, addr
+ IIC_CSR2
);
111 * wait_i2c_reg - waits the read/write to finish
113 * @addr: dt3155 mmio base address
115 * returns: zero on success or error code
117 * This function waits reading/writing to finish.
119 static int wait_i2c_reg(void __iomem
*addr
)
121 if (ioread32(addr
+ IIC_CSR2
) & NEW_CYCLE
)
122 udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */
123 if (ioread32(addr
+ IIC_CSR2
) & NEW_CYCLE
)
124 return -EIO
; /* error: NEW_CYCLE not cleared */
125 if (ioread32(addr
+ IIC_CSR1
) & DIRECT_ABORT
) {
126 /* reset DIRECT_ABORT bit */
127 iowrite32(DIRECT_ABORT
, addr
+ IIC_CSR1
);
128 return -EIO
; /* error: DIRECT_ABORT set */
134 dt3155_queue_setup(struct vb2_queue
*vq
, const void *parg
,
135 unsigned int *nbuffers
, unsigned int *num_planes
,
136 unsigned int sizes
[], void *alloc_ctxs
[])
139 const struct v4l2_format
*fmt
= parg
;
140 struct dt3155_priv
*pd
= vb2_get_drv_priv(vq
);
141 unsigned size
= pd
->width
* pd
->height
;
143 if (vq
->num_buffers
+ *nbuffers
< 2)
144 *nbuffers
= 2 - vq
->num_buffers
;
145 if (fmt
&& fmt
->fmt
.pix
.sizeimage
< size
)
148 sizes
[0] = fmt
? fmt
->fmt
.pix
.sizeimage
: size
;
149 alloc_ctxs
[0] = pd
->alloc_ctx
;
153 static int dt3155_buf_prepare(struct vb2_buffer
*vb
)
155 struct dt3155_priv
*pd
= vb2_get_drv_priv(vb
->vb2_queue
);
157 vb2_set_plane_payload(vb
, 0, pd
->width
* pd
->height
);
161 static int dt3155_start_streaming(struct vb2_queue
*q
, unsigned count
)
163 struct dt3155_priv
*pd
= vb2_get_drv_priv(q
);
164 struct vb2_buffer
*vb
= &pd
->curr_buf
->vb2_buf
;
168 dma_addr
= vb2_dma_contig_plane_dma_addr(vb
, 0);
169 iowrite32(dma_addr
, pd
->regs
+ EVEN_DMA_START
);
170 iowrite32(dma_addr
+ pd
->width
, pd
->regs
+ ODD_DMA_START
);
171 iowrite32(pd
->width
, pd
->regs
+ EVEN_DMA_STRIDE
);
172 iowrite32(pd
->width
, pd
->regs
+ ODD_DMA_STRIDE
);
173 /* enable interrupts, clear all irq flags */
174 iowrite32(FLD_START_EN
| FLD_END_ODD_EN
| FLD_START
|
175 FLD_END_EVEN
| FLD_END_ODD
, pd
->regs
+ INT_CSR
);
176 iowrite32(FIFO_EN
| SRST
| FLD_CRPT_ODD
| FLD_CRPT_EVEN
|
177 FLD_DN_ODD
| FLD_DN_EVEN
| CAP_CONT_EVEN
| CAP_CONT_ODD
,
179 wait_i2c_reg(pd
->regs
);
180 write_i2c_reg(pd
->regs
, CONFIG
, pd
->config
);
181 write_i2c_reg(pd
->regs
, EVEN_CSR
, CSR_ERROR
| CSR_DONE
);
182 write_i2c_reg(pd
->regs
, ODD_CSR
, CSR_ERROR
| CSR_DONE
);
184 /* start the board */
185 write_i2c_reg(pd
->regs
, CSR2
, pd
->csr2
| BUSY_EVEN
| BUSY_ODD
);
189 static void dt3155_stop_streaming(struct vb2_queue
*q
)
191 struct dt3155_priv
*pd
= vb2_get_drv_priv(q
);
192 struct vb2_buffer
*vb
;
194 spin_lock_irq(&pd
->lock
);
196 write_i2c_reg_nowait(pd
->regs
, CSR2
, pd
->csr2
);
197 iowrite32(FIFO_EN
| SRST
| FLD_CRPT_ODD
| FLD_CRPT_EVEN
|
198 FLD_DN_ODD
| FLD_DN_EVEN
, pd
->regs
+ CSR1
);
199 /* disable interrupts, clear all irq flags */
200 iowrite32(FLD_START
| FLD_END_EVEN
| FLD_END_ODD
, pd
->regs
+ INT_CSR
);
201 spin_unlock_irq(&pd
->lock
);
204 * It is not clear whether the DMA stops at once or whether it
205 * will finish the current frame or field first. To be on the
206 * safe side we wait a bit.
210 spin_lock_irq(&pd
->lock
);
212 vb2_buffer_done(&pd
->curr_buf
->vb2_buf
, VB2_BUF_STATE_ERROR
);
216 while (!list_empty(&pd
->dmaq
)) {
217 vb
= list_first_entry(&pd
->dmaq
, typeof(*vb
), done_entry
);
218 list_del(&vb
->done_entry
);
219 vb2_buffer_done(vb
, VB2_BUF_STATE_ERROR
);
221 spin_unlock_irq(&pd
->lock
);
224 static void dt3155_buf_queue(struct vb2_buffer
*vb
)
226 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
227 struct dt3155_priv
*pd
= vb2_get_drv_priv(vb
->vb2_queue
);
229 /* pd->vidq.streaming = 1 when dt3155_buf_queue() is invoked */
230 spin_lock_irq(&pd
->lock
);
232 list_add_tail(&vb
->done_entry
, &pd
->dmaq
);
235 spin_unlock_irq(&pd
->lock
);
238 static const struct vb2_ops q_ops
= {
239 .queue_setup
= dt3155_queue_setup
,
240 .wait_prepare
= vb2_ops_wait_prepare
,
241 .wait_finish
= vb2_ops_wait_finish
,
242 .buf_prepare
= dt3155_buf_prepare
,
243 .start_streaming
= dt3155_start_streaming
,
244 .stop_streaming
= dt3155_stop_streaming
,
245 .buf_queue
= dt3155_buf_queue
,
248 static irqreturn_t
dt3155_irq_handler_even(int irq
, void *dev_id
)
250 struct dt3155_priv
*ipd
= dev_id
;
251 struct vb2_buffer
*ivb
;
255 tmp
= ioread32(ipd
->regs
+ INT_CSR
) & (FLD_START
| FLD_END_ODD
);
257 return IRQ_NONE
; /* not our irq */
258 if ((tmp
& FLD_START
) && !(tmp
& FLD_END_ODD
)) {
259 iowrite32(FLD_START_EN
| FLD_END_ODD_EN
| FLD_START
,
260 ipd
->regs
+ INT_CSR
);
261 return IRQ_HANDLED
; /* start of field irq */
263 tmp
= ioread32(ipd
->regs
+ CSR1
) & (FLD_CRPT_EVEN
| FLD_CRPT_ODD
);
265 iowrite32(FIFO_EN
| SRST
| FLD_CRPT_ODD
| FLD_CRPT_EVEN
|
266 FLD_DN_ODD
| FLD_DN_EVEN
|
267 CAP_CONT_EVEN
| CAP_CONT_ODD
,
272 spin_lock(&ipd
->lock
);
273 if (ipd
->curr_buf
&& !list_empty(&ipd
->dmaq
)) {
274 v4l2_get_timestamp(&ipd
->curr_buf
->timestamp
);
275 ipd
->curr_buf
->sequence
= ipd
->sequence
++;
276 ipd
->curr_buf
->field
= V4L2_FIELD_NONE
;
277 vb2_buffer_done(&ipd
->curr_buf
->vb2_buf
, VB2_BUF_STATE_DONE
);
279 ivb
= list_first_entry(&ipd
->dmaq
, typeof(*ivb
), done_entry
);
280 list_del(&ivb
->done_entry
);
281 ipd
->curr_buf
= to_vb2_v4l2_buffer(ivb
);
282 dma_addr
= vb2_dma_contig_plane_dma_addr(ivb
, 0);
283 iowrite32(dma_addr
, ipd
->regs
+ EVEN_DMA_START
);
284 iowrite32(dma_addr
+ ipd
->width
, ipd
->regs
+ ODD_DMA_START
);
285 iowrite32(ipd
->width
, ipd
->regs
+ EVEN_DMA_STRIDE
);
286 iowrite32(ipd
->width
, ipd
->regs
+ ODD_DMA_STRIDE
);
290 /* enable interrupts, clear all irq flags */
291 iowrite32(FLD_START_EN
| FLD_END_ODD_EN
| FLD_START
|
292 FLD_END_EVEN
| FLD_END_ODD
, ipd
->regs
+ INT_CSR
);
293 spin_unlock(&ipd
->lock
);
297 static const struct v4l2_file_operations dt3155_fops
= {
298 .owner
= THIS_MODULE
,
299 .open
= v4l2_fh_open
,
300 .release
= vb2_fop_release
,
301 .unlocked_ioctl
= video_ioctl2
,
302 .read
= vb2_fop_read
,
303 .mmap
= vb2_fop_mmap
,
307 static int dt3155_querycap(struct file
*filp
, void *p
,
308 struct v4l2_capability
*cap
)
310 struct dt3155_priv
*pd
= video_drvdata(filp
);
312 strcpy(cap
->driver
, DT3155_NAME
);
313 strcpy(cap
->card
, DT3155_NAME
" frame grabber");
314 sprintf(cap
->bus_info
, "PCI:%s", pci_name(pd
->pdev
));
315 cap
->device_caps
= V4L2_CAP_VIDEO_CAPTURE
|
316 V4L2_CAP_STREAMING
| V4L2_CAP_READWRITE
;
317 cap
->capabilities
= cap
->device_caps
| V4L2_CAP_DEVICE_CAPS
;
321 static int dt3155_enum_fmt_vid_cap(struct file
*filp
,
322 void *p
, struct v4l2_fmtdesc
*f
)
326 f
->pixelformat
= V4L2_PIX_FMT_GREY
;
327 strcpy(f
->description
, "8-bit Greyscale");
331 static int dt3155_fmt_vid_cap(struct file
*filp
, void *p
, struct v4l2_format
*f
)
333 struct dt3155_priv
*pd
= video_drvdata(filp
);
335 f
->fmt
.pix
.width
= pd
->width
;
336 f
->fmt
.pix
.height
= pd
->height
;
337 f
->fmt
.pix
.pixelformat
= V4L2_PIX_FMT_GREY
;
338 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
339 f
->fmt
.pix
.bytesperline
= f
->fmt
.pix
.width
;
340 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.width
* f
->fmt
.pix
.height
;
341 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
345 static int dt3155_g_std(struct file
*filp
, void *p
, v4l2_std_id
*norm
)
347 struct dt3155_priv
*pd
= video_drvdata(filp
);
353 static int dt3155_s_std(struct file
*filp
, void *p
, v4l2_std_id norm
)
355 struct dt3155_priv
*pd
= video_drvdata(filp
);
359 if (vb2_is_busy(&pd
->vidq
))
362 if (pd
->std
& V4L2_STD_525_60
) {
374 static int dt3155_enum_input(struct file
*filp
, void *p
,
375 struct v4l2_input
*input
)
377 if (input
->index
> 3)
380 snprintf(input
->name
, sizeof(input
->name
), "VID%d",
383 strlcpy(input
->name
, "J2/VID0", sizeof(input
->name
));
384 input
->type
= V4L2_INPUT_TYPE_CAMERA
;
385 input
->std
= V4L2_STD_ALL
;
390 static int dt3155_g_input(struct file
*filp
, void *p
, unsigned int *i
)
392 struct dt3155_priv
*pd
= video_drvdata(filp
);
398 static int dt3155_s_input(struct file
*filp
, void *p
, unsigned int i
)
400 struct dt3155_priv
*pd
= video_drvdata(filp
);
405 write_i2c_reg(pd
->regs
, AD_ADDR
, AD_CMD_REG
);
406 write_i2c_reg(pd
->regs
, AD_CMD
, (i
<< 6) | (i
<< 4) | SYNC_LVL_3
);
410 static const struct v4l2_ioctl_ops dt3155_ioctl_ops
= {
411 .vidioc_querycap
= dt3155_querycap
,
412 .vidioc_enum_fmt_vid_cap
= dt3155_enum_fmt_vid_cap
,
413 .vidioc_try_fmt_vid_cap
= dt3155_fmt_vid_cap
,
414 .vidioc_g_fmt_vid_cap
= dt3155_fmt_vid_cap
,
415 .vidioc_s_fmt_vid_cap
= dt3155_fmt_vid_cap
,
416 .vidioc_reqbufs
= vb2_ioctl_reqbufs
,
417 .vidioc_create_bufs
= vb2_ioctl_create_bufs
,
418 .vidioc_querybuf
= vb2_ioctl_querybuf
,
419 .vidioc_expbuf
= vb2_ioctl_expbuf
,
420 .vidioc_qbuf
= vb2_ioctl_qbuf
,
421 .vidioc_dqbuf
= vb2_ioctl_dqbuf
,
422 .vidioc_streamon
= vb2_ioctl_streamon
,
423 .vidioc_streamoff
= vb2_ioctl_streamoff
,
424 .vidioc_g_std
= dt3155_g_std
,
425 .vidioc_s_std
= dt3155_s_std
,
426 .vidioc_enum_input
= dt3155_enum_input
,
427 .vidioc_g_input
= dt3155_g_input
,
428 .vidioc_s_input
= dt3155_s_input
,
431 static int dt3155_init_board(struct dt3155_priv
*pd
)
433 struct pci_dev
*pdev
= pd
->pdev
;
437 pci_set_master(pdev
); /* dt3155 needs it */
439 /* resetting the adapter */
440 iowrite32(ADDR_ERR_ODD
| ADDR_ERR_EVEN
| FLD_CRPT_ODD
| FLD_CRPT_EVEN
|
441 FLD_DN_ODD
| FLD_DN_EVEN
, pd
->regs
+ CSR1
);
445 /* initializing adapter registers */
446 iowrite32(FIFO_EN
| SRST
, pd
->regs
+ CSR1
);
448 iowrite32(0xEEEEEE01, pd
->regs
+ EVEN_PIXEL_FMT
);
449 iowrite32(0xEEEEEE01, pd
->regs
+ ODD_PIXEL_FMT
);
450 iowrite32(0x00000020, pd
->regs
+ FIFO_TRIGER
);
451 iowrite32(0x00000103, pd
->regs
+ XFER_MODE
);
452 iowrite32(0, pd
->regs
+ RETRY_WAIT_CNT
);
453 iowrite32(0, pd
->regs
+ INT_CSR
);
454 iowrite32(1, pd
->regs
+ EVEN_FLD_MASK
);
455 iowrite32(1, pd
->regs
+ ODD_FLD_MASK
);
456 iowrite32(0, pd
->regs
+ MASK_LENGTH
);
457 iowrite32(0x0005007C, pd
->regs
+ FIFO_FLAG_CNT
);
458 iowrite32(0x01010101, pd
->regs
+ IIC_CLK_DUR
);
461 /* verifying that we have a DT3155 board (not just a SAA7116 chip) */
462 read_i2c_reg(pd
->regs
, DT_ID
, &tmp
);
463 if (tmp
!= DT3155_ID
)
466 /* initialize AD LUT */
467 write_i2c_reg(pd
->regs
, AD_ADDR
, 0);
468 for (i
= 0; i
< 256; i
++)
469 write_i2c_reg(pd
->regs
, AD_LUT
, i
);
471 /* initialize ADC references */
472 /* FIXME: pos_ref & neg_ref depend on VT_50HZ */
473 write_i2c_reg(pd
->regs
, AD_ADDR
, AD_CMD_REG
);
474 write_i2c_reg(pd
->regs
, AD_CMD
, VIDEO_CNL_1
| SYNC_CNL_1
| SYNC_LVL_3
);
475 write_i2c_reg(pd
->regs
, AD_ADDR
, AD_POS_REF
);
476 write_i2c_reg(pd
->regs
, AD_CMD
, 34);
477 write_i2c_reg(pd
->regs
, AD_ADDR
, AD_NEG_REF
);
478 write_i2c_reg(pd
->regs
, AD_CMD
, 0);
480 /* initialize PM LUT */
481 write_i2c_reg(pd
->regs
, CONFIG
, pd
->config
| PM_LUT_PGM
);
482 for (i
= 0; i
< 256; i
++) {
483 write_i2c_reg(pd
->regs
, PM_LUT_ADDR
, i
);
484 write_i2c_reg(pd
->regs
, PM_LUT_DATA
, i
);
486 write_i2c_reg(pd
->regs
, CONFIG
, pd
->config
| PM_LUT_PGM
| PM_LUT_SEL
);
487 for (i
= 0; i
< 256; i
++) {
488 write_i2c_reg(pd
->regs
, PM_LUT_ADDR
, i
);
489 write_i2c_reg(pd
->regs
, PM_LUT_DATA
, i
);
491 write_i2c_reg(pd
->regs
, CONFIG
, pd
->config
); /* ACQ_MODE_EVEN */
493 /* select channel 1 for input and set sync level */
494 write_i2c_reg(pd
->regs
, AD_ADDR
, AD_CMD_REG
);
495 write_i2c_reg(pd
->regs
, AD_CMD
, VIDEO_CNL_1
| SYNC_CNL_1
| SYNC_LVL_3
);
497 /* disable all irqs, clear all irq flags */
498 iowrite32(FLD_START
| FLD_END_EVEN
| FLD_END_ODD
,
504 static struct video_device dt3155_vdev
= {
506 .fops
= &dt3155_fops
,
507 .ioctl_ops
= &dt3155_ioctl_ops
,
509 .release
= video_device_release_empty
,
510 .tvnorms
= V4L2_STD_ALL
,
513 static int dt3155_probe(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
516 struct dt3155_priv
*pd
;
518 err
= dma_set_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(32));
521 pd
= devm_kzalloc(&pdev
->dev
, sizeof(*pd
), GFP_KERNEL
);
525 err
= v4l2_device_register(&pdev
->dev
, &pd
->v4l2_dev
);
528 pd
->vdev
= dt3155_vdev
;
529 pd
->vdev
.v4l2_dev
= &pd
->v4l2_dev
;
530 video_set_drvdata(&pd
->vdev
, pd
); /* for use in video_fops */
532 pd
->std
= V4L2_STD_625_50
;
536 INIT_LIST_HEAD(&pd
->dmaq
);
537 mutex_init(&pd
->mux
);
538 pd
->vdev
.lock
= &pd
->mux
; /* for locking v4l2_file_operations */
539 pd
->vidq
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
540 pd
->vidq
.timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
541 pd
->vidq
.io_modes
= VB2_MMAP
| VB2_DMABUF
| VB2_READ
;
542 pd
->vidq
.ops
= &q_ops
;
543 pd
->vidq
.mem_ops
= &vb2_dma_contig_memops
;
544 pd
->vidq
.drv_priv
= pd
;
545 pd
->vidq
.min_buffers_needed
= 2;
546 pd
->vidq
.gfp_flags
= GFP_DMA32
;
547 pd
->vidq
.lock
= &pd
->mux
; /* for locking v4l2_file_operations */
548 pd
->vdev
.queue
= &pd
->vidq
;
549 err
= vb2_queue_init(&pd
->vidq
);
551 goto err_v4l2_dev_unreg
;
552 pd
->alloc_ctx
= vb2_dma_contig_init_ctx(&pdev
->dev
);
553 if (IS_ERR(pd
->alloc_ctx
)) {
554 dev_err(&pdev
->dev
, "Can't allocate buffer context");
555 err
= PTR_ERR(pd
->alloc_ctx
);
556 goto err_v4l2_dev_unreg
;
558 spin_lock_init(&pd
->lock
);
559 pd
->config
= ACQ_MODE_EVEN
;
560 err
= pci_enable_device(pdev
);
563 err
= pci_request_region(pdev
, 0, pci_name(pdev
));
565 goto err_pci_disable
;
566 pd
->regs
= pci_iomap(pdev
, 0, pci_resource_len(pd
->pdev
, 0));
571 err
= dt3155_init_board(pd
);
574 err
= request_irq(pd
->pdev
->irq
, dt3155_irq_handler_even
,
575 IRQF_SHARED
, DT3155_NAME
, pd
);
578 err
= video_register_device(&pd
->vdev
, VFL_TYPE_GRABBER
, -1);
581 dev_info(&pdev
->dev
, "/dev/video%i is ready\n", pd
->vdev
.minor
);
582 return 0; /* success */
585 free_irq(pd
->pdev
->irq
, pd
);
587 pci_iounmap(pdev
, pd
->regs
);
589 pci_release_region(pdev
, 0);
591 pci_disable_device(pdev
);
593 vb2_dma_contig_cleanup_ctx(pd
->alloc_ctx
);
595 v4l2_device_unregister(&pd
->v4l2_dev
);
599 static void dt3155_remove(struct pci_dev
*pdev
)
601 struct v4l2_device
*v4l2_dev
= pci_get_drvdata(pdev
);
602 struct dt3155_priv
*pd
= container_of(v4l2_dev
, struct dt3155_priv
,
605 video_unregister_device(&pd
->vdev
);
606 free_irq(pd
->pdev
->irq
, pd
);
607 vb2_queue_release(&pd
->vidq
);
608 v4l2_device_unregister(&pd
->v4l2_dev
);
609 pci_iounmap(pdev
, pd
->regs
);
610 pci_release_region(pdev
, 0);
611 pci_disable_device(pdev
);
612 vb2_dma_contig_cleanup_ctx(pd
->alloc_ctx
);
615 static const struct pci_device_id pci_ids
[] = {
616 { PCI_DEVICE(PCI_VENDOR_ID_INTEL
, DT3155_DEVICE_ID
) },
617 { 0, /* zero marks the end */ },
619 MODULE_DEVICE_TABLE(pci
, pci_ids
);
621 static struct pci_driver pci_driver
= {
624 .probe
= dt3155_probe
,
625 .remove
= dt3155_remove
,
628 module_pci_driver(pci_driver
);
630 MODULE_DESCRIPTION("video4linux pci-driver for dt3155 frame grabber");
631 MODULE_AUTHOR("Marin Mitov <mitov@issp.bas.bg>");
632 MODULE_VERSION(DT3155_VERSION
);
633 MODULE_LICENSE("GPL");