Staging: crystalhd: Remove typedefs from driver
[deliverable/linux.git] / drivers / staging / dt3155v4l / dt3155v4l.c
CommitLineData
717f4a5f
MM
1/***************************************************************************
2 * Copyright (C) 2006-2010 by Marin Mitov *
3 * mitov@issp.bas.bg *
4 * *
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. *
9 * *
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. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
d42bffb8
MM
21#include <media/v4l2-dev.h>
22#include <media/videobuf-core.h>
23#include <media/v4l2-ioctl.h>
24#include <linux/pci.h>
25#include <linux/version.h>
26#include <linux/stringify.h>
7ec21181 27#include <linux/delay.h>
d42bffb8
MM
28#include <media/videobuf-dma-contig.h>
29#include <linux/kthread.h>
30
31#include "dt3155v4l.h"
32#include "dt3155-bufs.h"
33
34#define DT3155_VENDOR_ID 0x8086
35#define DT3155_DEVICE_ID 0x1223
36
37/* global initializers (for all boards) */
38#ifdef CONFIG_DT3155_CCIR
39static const u8 csr2_init = VT_50HZ;
40#define DT3155_CURRENT_NORM V4L2_STD_625_50
41static const unsigned int img_width = 768;
42static const unsigned int img_height = 576;
43static const unsigned int frames_per_sec = 25;
44static const struct v4l2_fmtdesc frame_std[] = {
45 {
46 .index = 0,
47 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
48 .flags = 0,
49 .description = "CCIR/50Hz 8 bits gray",
50 .pixelformat = V4L2_PIX_FMT_GREY,
51 },
52};
53#else
54static const u8 csr2_init = VT_60HZ;
55#define DT3155_CURRENT_NORM V4L2_STD_525_60
56static const unsigned int img_width = 640;
57static const unsigned int img_height = 480;
58static const unsigned int frames_per_sec = 30;
59static const struct v4l2_fmtdesc frame_std[] = {
60 {
61 .index = 0,
62 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
63 .flags = 0,
64 .description = "RS-170/60Hz 8 bits gray",
65 .pixelformat = V4L2_PIX_FMT_GREY,
66 },
67};
68#endif
69
70#define NUM_OF_FORMATS ARRAY_SIZE(frame_std)
71
72static u8 config_init = ACQ_MODE_EVEN;
73
74/**
75 * read_i2c_reg - reads an internal i2c register
76 *
77 * @addr: dt3155 mmio base address
78 * @index: index (internal address) of register to read
79 * @data: pointer to byte the read data will be placed in
80 *
81 * returns: zero on success or error code
82 *
83 * This function starts reading the specified (by index) register
84 * and busy waits for the process to finish. The result is placed
85 * in a byte pointed by data.
86 */
87static int
2342df0e 88read_i2c_reg(void __iomem *addr, u8 index, u8 *data)
d42bffb8
MM
89{
90 u32 tmp = index;
91
92 iowrite32((tmp<<17) | IIC_READ, addr + IIC_CSR2);
93 mmiowb();
94 udelay(45); /* wait at least 43 usec for NEW_CYCLE to clear */
95 if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) {
96 /* error: NEW_CYCLE not cleared */
97 printk(KERN_ERR "dt3155: NEW_CYCLE not cleared\n");
98 return -EIO;
99 }
100 tmp = ioread32(addr + IIC_CSR1);
101 if (tmp & DIRECT_ABORT) {
102 /* error: DIRECT_ABORT set */
103 printk(KERN_ERR "dt3155: DIRECT_ABORT set\n");
104 /* reset DIRECT_ABORT bit */
105 iowrite32(DIRECT_ABORT, addr + IIC_CSR1);
106 return -EIO;
107 }
108 *data = tmp>>24;
109 return 0;
110}
111
112/**
113 * write_i2c_reg - writes to an internal i2c register
114 *
115 * @addr: dt3155 mmio base address
116 * @index: index (internal address) of register to read
117 * @data: data to be written
118 *
119 * returns: zero on success or error code
120 *
121 * This function starts writting the specified (by index) register
122 * and busy waits for the process to finish.
123 */
124static int
2342df0e 125write_i2c_reg(void __iomem *addr, u8 index, u8 data)
d42bffb8
MM
126{
127 u32 tmp = index;
128
129 iowrite32((tmp<<17) | IIC_WRITE | data, addr + IIC_CSR2);
130 mmiowb();
131 udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */
132 if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) {
133 /* error: NEW_CYCLE not cleared */
134 printk(KERN_ERR "dt3155: NEW_CYCLE not cleared\n");
135 return -EIO;
136 }
137 if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) {
138 /* error: DIRECT_ABORT set */
139 printk(KERN_ERR "dt3155: DIRECT_ABORT set\n");
140 /* reset DIRECT_ABORT bit */
141 iowrite32(DIRECT_ABORT, addr + IIC_CSR1);
142 return -EIO;
143 }
144 return 0;
145}
146
147/**
148 * write_i2c_reg_nowait - writes to an internal i2c register
149 *
150 * @addr: dt3155 mmio base address
151 * @index: index (internal address) of register to read
152 * @data: data to be written
153 *
154 * This function starts writting the specified (by index) register
155 * and then returns.
156 */
2342df0e 157static void write_i2c_reg_nowait(void __iomem *addr, u8 index, u8 data)
d42bffb8
MM
158{
159 u32 tmp = index;
160
161 iowrite32((tmp<<17) | IIC_WRITE | data, addr + IIC_CSR2);
162 mmiowb();
163}
164
165/**
166 * wait_i2c_reg - waits the read/write to finish
167 *
168 * @addr: dt3155 mmio base address
169 *
170 * returns: zero on success or error code
171 *
172 * This function waits reading/writting to finish.
173 */
2342df0e 174static int wait_i2c_reg(void __iomem *addr)
d42bffb8
MM
175{
176 if (ioread32(addr + IIC_CSR2) & NEW_CYCLE)
177 udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */
178 if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) {
179 /* error: NEW_CYCLE not cleared */
180 printk(KERN_ERR "dt3155: NEW_CYCLE not cleared\n");
181 return -EIO;
182 }
183 if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) {
184 /* error: DIRECT_ABORT set */
185 printk(KERN_ERR "dt3155: DIRECT_ABORT set\n");
186 /* reset DIRECT_ABORT bit */
187 iowrite32(DIRECT_ABORT, addr + IIC_CSR1);
188 return -EIO;
189 }
190 return 0;
191}
192
193/*
194 * global pointers to a list of 4MB chunks reserved at driver
195 * load, broken down to contiguous buffers of 768 * 576 bytes
196 * each to form a pool of buffers for allocations
197 * FIXME: add spinlock to protect moves between alloc/free lists
198 */
199static struct dt3155_fifo *dt3155_chunks; /* list of 4MB chuncks */
200static struct dt3155_fifo *dt3155_free_bufs; /* list of free buffers */
201static struct dt3155_fifo *dt3155_alloc_bufs; /* list of allocated buffers */
202
203/* same as in <drivers/media/video/videobuf-dma-contig.c> */
204struct videobuf_dma_contig_memory {
205 u32 magic;
206 void *vaddr;
207 dma_addr_t dma_handle;
208 unsigned long size;
209 int is_userptr;
210};
211
212#define MAGIC_DC_MEM 0x0733ac61
213#define MAGIC_CHECK(is, should) \
214 if (unlikely((is) != (should))) { \
215 pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
216 BUG(); \
217 }
218
219/* helper functions to allocate/free buffers from the pool */
220static void *
221dt3155_alloc_buffer(struct device *dev, size_t size, dma_addr_t *dma_handle,
222 gfp_t flag)
223{
224 struct dt3155_buf *buf;
225
226 if (size > DT3155_BUF_SIZE)
227 return NULL;
228 size = DT3155_BUF_SIZE; /* same for CCIR & RS-170 */
229 buf = dt3155_get_buf(dt3155_free_bufs);
230 if (!buf)
231 return NULL;
232 buf->dma = dma_map_single(dev, buf->cpu, size, DMA_FROM_DEVICE);
233 if (dma_mapping_error(dev, buf->dma)) {
234 dt3155_put_buf(buf, dt3155_free_bufs);
235 return NULL;
236 }
237 dt3155_put_buf(buf, dt3155_alloc_bufs);
238 *dma_handle = buf->dma;
239 return buf->cpu;
240}
241
242static void
243dt3155_free_buffer(struct device *dev, size_t size, void *cpu_addr,
244 dma_addr_t dma_handle)
245{
246 struct dt3155_buf *buf, *last;
247 int found = 0;
248
249 if (!cpu_addr) /* to free NULL is OK */
250 return;
251 last = dt3155_get_buf(dt3155_alloc_bufs);
252 if (!last) {
253 printk(KERN_ERR "dt3155: %s(): no alloc buffers\n", __func__);
254 return;
255 }
256 dt3155_put_buf(last, dt3155_alloc_bufs);
257 do {
258 buf = dt3155_get_buf(dt3155_alloc_bufs);
259 if (buf->cpu == cpu_addr && buf->dma == dma_handle) {
260 found = 1;
261 break;
262 }
263 dt3155_put_buf(buf, dt3155_alloc_bufs);
264 } while (buf != last);
265 if (!found) {
266 printk(KERN_ERR "dt3155: %s(): buffer not found\n", __func__);
267 return;
268 }
269 size = DT3155_BUF_SIZE; /* same for CCIR & RS-170 */
270 dma_unmap_single(dev, dma_handle, size, DMA_FROM_DEVICE);
271 dt3155_put_buf(buf, dt3155_free_bufs);
272}
273
274/* same as videobuf_dma_contig_user_get() */
275static int
276dt3155_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
277 struct videobuf_buffer *vb)
278{
279 struct mm_struct *mm = current->mm;
280 struct vm_area_struct *vma;
281 unsigned long prev_pfn, this_pfn;
282 unsigned long pages_done, user_address;
717f4a5f 283 unsigned int offset;
d42bffb8
MM
284 int ret;
285
717f4a5f
MM
286 offset = vb->baddr & ~PAGE_MASK;
287 mem->size = PAGE_ALIGN(vb->size + offset);
d42bffb8
MM
288 mem->is_userptr = 0;
289 ret = -EINVAL;
290
291 down_read(&mm->mmap_sem);
292
293 vma = find_vma(mm, vb->baddr);
294 if (!vma)
295 goto out_up;
296
297 if ((vb->baddr + mem->size) > vma->vm_end)
298 goto out_up;
299
300 pages_done = 0;
301 prev_pfn = 0; /* kill warning */
302 user_address = vb->baddr;
303
304 while (pages_done < (mem->size >> PAGE_SHIFT)) {
305 ret = follow_pfn(vma, user_address, &this_pfn);
306 if (ret)
307 break;
308
309 if (pages_done == 0)
717f4a5f 310 mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset;
d42bffb8
MM
311 else if (this_pfn != (prev_pfn + 1))
312 ret = -EFAULT;
313
314 if (ret)
315 break;
316
317 prev_pfn = this_pfn;
318 user_address += PAGE_SIZE;
319 pages_done++;
320 }
321
322 if (!ret)
323 mem->is_userptr = 1;
324
325 out_up:
326 up_read(&current->mm->mmap_sem);
327
328 return ret;
329}
330
331/* same as videobuf_dma_contig_user_put() */
332static void
333dt3155_dma_contig_user_put(struct videobuf_dma_contig_memory *mem)
334{
335 mem->is_userptr = 0;
336 mem->dma_handle = 0;
337 mem->size = 0;
338}
339
340/* same as videobuf_iolock() but uses allocations from the pool */
341static int
342dt3155_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb,
343 struct v4l2_framebuffer *fbuf)
344{
345 struct videobuf_dma_contig_memory *mem = vb->priv;
346
347 BUG_ON(!mem);
348 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
349
350 switch (vb->memory) {
351 case V4L2_MEMORY_MMAP:
352 dev_dbg(q->dev, "%s memory method MMAP\n", __func__);
353
354 /* All handling should be done by __videobuf_mmap_mapper() */
355 if (!mem->vaddr) {
356 dev_err(q->dev, "memory is not alloced/mmapped.\n");
357 return -EINVAL;
358 }
359 break;
360 case V4L2_MEMORY_USERPTR:
361 dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
362
363 /* handle pointer from user space */
364 if (vb->baddr)
365 return dt3155_dma_contig_user_get(mem, vb);
366
367 /* allocate memory for the read() method */
368 mem->size = PAGE_ALIGN(vb->size);
369 mem->vaddr = dt3155_alloc_buffer(q->dev, mem->size,
370 &mem->dma_handle, GFP_KERNEL);
371 if (!mem->vaddr) {
372 dev_err(q->dev, "dma_alloc_coherent %ld failed\n",
373 mem->size);
374 return -ENOMEM;
375 }
376
377 dev_dbg(q->dev, "dma_alloc_coherent data is at %p (%ld)\n",
378 mem->vaddr, mem->size);
379 break;
380 case V4L2_MEMORY_OVERLAY:
381 default:
382 dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n",
383 __func__);
384 return -EINVAL;
385 }
386
387 return 0;
388}
389
390/* same as videobuf_dma_contig_free() but uses the pool */
391void
392dt3155_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf)
393{
394 struct videobuf_dma_contig_memory *mem = buf->priv;
395
396 /* mmapped memory can't be freed here, otherwise mmapped region
397 would be released, while still needed. In this case, the memory
398 release should happen inside videobuf_vm_close().
399 So, it should free memory only if the memory were allocated for
400 read() operation.
401 */
402 if (buf->memory != V4L2_MEMORY_USERPTR)
403 return;
404
405 if (!mem)
406 return;
407
408 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
409
410 /* handle user space pointer case */
411 if (buf->baddr) {
412 dt3155_dma_contig_user_put(mem);
413 return;
414 }
415
416 /* read() method */
417 dt3155_free_buffer(q->dev, mem->size, mem->vaddr, mem->dma_handle);
418 mem->vaddr = NULL;
419}
420
421/* same as videobuf_vm_open() */
422static void
423dt3155_vm_open(struct vm_area_struct *vma)
424{
425 struct videobuf_mapping *map = vma->vm_private_data;
426
427 dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
428 map, map->count, vma->vm_start, vma->vm_end);
429
430 map->count++;
431}
432
433/* same as videobuf_vm_close(), but free to the pool */
434static void
435dt3155_vm_close(struct vm_area_struct *vma)
436{
437 struct videobuf_mapping *map = vma->vm_private_data;
438 struct videobuf_queue *q = map->q;
439 int i;
440
717f4a5f 441 dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
d42bffb8
MM
442 map, map->count, vma->vm_start, vma->vm_end);
443
444 map->count--;
445 if (0 == map->count) {
446 struct videobuf_dma_contig_memory *mem;
447
717f4a5f 448 dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
d42bffb8
MM
449 mutex_lock(&q->vb_lock);
450
451 /* We need first to cancel streams, before unmapping */
452 if (q->streaming)
453 videobuf_queue_cancel(q);
454
455 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
456 if (NULL == q->bufs[i])
457 continue;
458
459 if (q->bufs[i]->map != map)
460 continue;
461
462 mem = q->bufs[i]->priv;
463 if (mem) {
464 /* This callback is called only if kernel has
465 allocated memory and this memory is mmapped.
466 In this case, memory should be freed,
467 in order to do memory unmap.
468 */
469
470 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
471
472 /* vfree is not atomic - can't be
473 called with IRQ's disabled
474 */
717f4a5f 475 dev_dbg(q->dev, "buf[%d] freeing %p\n",
d42bffb8
MM
476 i, mem->vaddr);
477
478 dt3155_free_buffer(q->dev, mem->size,
479 mem->vaddr, mem->dma_handle);
480 mem->vaddr = NULL;
481 }
482
483 q->bufs[i]->map = NULL;
484 q->bufs[i]->baddr = 0;
485 }
486
487 kfree(map);
488
489 mutex_unlock(&q->vb_lock);
490 }
491}
492
493static const struct vm_operations_struct dt3155_vm_ops = {
494 .open = dt3155_vm_open,
495 .close = dt3155_vm_close,
496};
497
498/* same as videobuf_mmap_mapper(), but allocates from the pool */
499static int
717f4a5f
MM
500dt3155_mmap_mapper(struct videobuf_queue *q, struct videobuf_buffer *buf,
501 struct vm_area_struct *vma)
d42bffb8
MM
502{
503 struct videobuf_dma_contig_memory *mem;
504 struct videobuf_mapping *map;
d42bffb8 505 int retval;
717f4a5f 506 unsigned long size;
d42bffb8
MM
507
508 dev_dbg(q->dev, "%s\n", __func__);
d42bffb8
MM
509
510 /* create mapping + update buffer list */
511 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
512 if (!map)
513 return -ENOMEM;
514
717f4a5f 515 buf->map = map;
d42bffb8
MM
516 map->start = vma->vm_start;
517 map->end = vma->vm_end;
518 map->q = q;
519
717f4a5f 520 buf->baddr = vma->vm_start;
d42bffb8 521
717f4a5f 522 mem = buf->priv;
d42bffb8
MM
523 BUG_ON(!mem);
524 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
525
717f4a5f 526 mem->size = PAGE_ALIGN(buf->bsize);
d42bffb8
MM
527 mem->vaddr = dt3155_alloc_buffer(q->dev, mem->size,
528 &mem->dma_handle, GFP_KERNEL);
529 if (!mem->vaddr) {
530 dev_err(q->dev, "dma_alloc_coherent size %ld failed\n",
531 mem->size);
532 goto error;
533 }
534 dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n",
535 mem->vaddr, mem->size);
536
537 /* Try to remap memory */
538
539 size = vma->vm_end - vma->vm_start;
540 size = (size < mem->size) ? size : mem->size;
541
542 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
543 retval = remap_pfn_range(vma, vma->vm_start,
544 mem->dma_handle >> PAGE_SHIFT,
545 size, vma->vm_page_prot);
546 if (retval) {
547 dev_err(q->dev, "mmap: remap failed with error %d. ", retval);
548 dt3155_free_buffer(q->dev, mem->size,
549 mem->vaddr, mem->dma_handle);
550 goto error;
551 }
552
553 vma->vm_ops = &dt3155_vm_ops;
554 vma->vm_flags |= VM_DONTEXPAND;
555 vma->vm_private_data = map;
556
557 dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
558 map, q, vma->vm_start, vma->vm_end,
717f4a5f
MM
559 (long int)buf->bsize,
560 vma->vm_pgoff, buf->i);
d42bffb8
MM
561
562 dt3155_vm_open(vma);
563
564 return 0;
565
566error:
567 kfree(map);
568 return -ENOMEM;
569}
570
571static int
572dt3155_sync_for_cpu(struct videobuf_queue *q, struct videobuf_buffer *vb)
573{
574 struct dt3155_priv *pd = q->priv_data;
575 struct videobuf_dma_contig_memory *mem = vb->priv;
576
577 BUG_ON(!mem);
578 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
579
580 pci_dma_sync_single_for_cpu(pd->pdev, mem->dma_handle,
581 mem->size, PCI_DMA_FROMDEVICE);
582 return 0;
583}
584
585static int
586dt3155_sync_for_device(struct videobuf_queue *q, struct videobuf_buffer *vb)
587{
588 struct dt3155_priv *pd = q->priv_data;
589 struct videobuf_dma_contig_memory *mem = vb->priv;
590
591 BUG_ON(!mem);
592 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
593
594 pci_dma_sync_single_for_device(pd->pdev, mem->dma_handle,
595 mem->size, PCI_DMA_FROMDEVICE);
596 return 0;
597}
598
599/*
600 * same as videobuf_queue_dma_contig_init(), but after
601 * initialisation overwrites videobuf_iolock() and
602 * videobuf_mmap_mapper() with our customized versions
603 * as well as adds sync() method
604 */
605static void
606dt3155_queue_dma_contig_init(struct videobuf_queue *q,
607 struct videobuf_queue_ops *ops,
608 struct device *dev,
609 spinlock_t *irqlock,
610 enum v4l2_buf_type type,
611 enum v4l2_field field,
612 unsigned int msize,
613 void *priv)
614{
ad602259 615 struct dt3155_priv *pd = priv;
b8aab127 616
d42bffb8
MM
617 videobuf_queue_dma_contig_init(q, ops, dev, irqlock,
618 type, field, msize, priv);
b8aab127
MM
619 /* replace with local copy */
620 pd->qt_ops = *q->int_ops;
621 q->int_ops = &pd->qt_ops;
622 /* and overwrite with our methods */
d42bffb8
MM
623 q->int_ops->iolock = dt3155_iolock;
624 q->int_ops->mmap_mapper = dt3155_mmap_mapper;
625 q->int_ops->sync = dt3155_sync_for_cpu;
626}
627
628static int
629dt3155_start_acq(struct dt3155_priv *pd)
630{
631 struct videobuf_buffer *vb = pd->curr_buf;
632 dma_addr_t dma_addr;
633
634 dma_addr = videobuf_to_dma_contig(vb);
635 iowrite32(dma_addr, pd->regs + EVEN_DMA_START);
636 iowrite32(dma_addr + vb->width, pd->regs + ODD_DMA_START);
637 iowrite32(vb->width, pd->regs + EVEN_DMA_STRIDE);
638 iowrite32(vb->width, pd->regs + ODD_DMA_STRIDE);
639 /* enable interrupts, clear all irq flags */
640 iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START |
641 FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR);
642 iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN |
643 FLD_DN_ODD | FLD_DN_EVEN | CAP_CONT_EVEN | CAP_CONT_ODD,
644 pd->regs + CSR1);
645 wait_i2c_reg(pd->regs);
646 write_i2c_reg(pd->regs, CONFIG, pd->config);
647 write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE);
648 write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_DONE);
649
650 /* start the board */
651 write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | BUSY_ODD);
652 return 0; /* success */
653}
654
655static int
656dt3155_stop_acq(struct dt3155_priv *pd)
657{
658 int tmp;
659
660 /* stop the board */
661 wait_i2c_reg(pd->regs);
662 write_i2c_reg(pd->regs, CSR2, pd->csr2);
663
664 /* disable all irqs, clear all irq flags */
665 iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR);
666 write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE);
667 write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_DONE);
668 tmp = ioread32(pd->regs + CSR1) & (FLD_CRPT_EVEN | FLD_CRPT_ODD);
669 if (tmp)
670 printk(KERN_ERR "dt3155: corrupted field %u\n", tmp);
671 iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN |
672 FLD_DN_ODD | FLD_DN_EVEN | CAP_CONT_EVEN | CAP_CONT_ODD,
673 pd->regs + CSR1);
674 return 0;
675}
676
677/* Locking: Caller holds q->vb_lock */
678static int
679dt3155_buf_setup(struct videobuf_queue *q, unsigned int *count,
680 unsigned int *size)
681{
682 *size = img_width * img_height;
683 return 0;
684}
685
686/* Locking: Caller holds q->vb_lock */
687static int
688dt3155_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
689 enum v4l2_field field)
690{
691 int ret = 0;
692
693 vb->width = img_width;
694 vb->height = img_height;
695 vb->size = img_width * img_height;
696 vb->field = field;
697 if (vb->state == VIDEOBUF_NEEDS_INIT)
698 ret = videobuf_iolock(q, vb, NULL);
699 if (ret) {
700 vb->state = VIDEOBUF_ERROR;
701 printk(KERN_ERR "ERROR: videobuf_iolock() failed\n");
702 videobuf_dma_contig_free(q, vb);
703 } else
704 vb->state = VIDEOBUF_PREPARED;
705 return ret;
706}
707
708/* Locking: Caller holds q->vb_lock & q->irqlock */
709static void
710dt3155_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
711{
712 struct dt3155_priv *pd = q->priv_data;
713
714 if (vb->state != VIDEOBUF_NEEDS_INIT) {
715 vb->state = VIDEOBUF_QUEUED;
716 dt3155_sync_for_device(q, vb);
717 list_add_tail(&vb->queue, &pd->dmaq);
718 wake_up_interruptible_sync(&pd->do_dma);
719 } else
720 vb->state = VIDEOBUF_ERROR;
721}
722
723/* Locking: Caller holds q->vb_lock */
724static void
725dt3155_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
726{
727 if (vb->state == VIDEOBUF_ACTIVE)
728 videobuf_waiton(vb, 0, 0); /* FIXME: cannot be interrupted */
729 dt3155_dma_contig_free(q, vb);
730 vb->state = VIDEOBUF_NEEDS_INIT;
731}
732
733static struct videobuf_queue_ops vbq_ops = {
734 .buf_setup = dt3155_buf_setup,
735 .buf_prepare = dt3155_buf_prepare,
736 .buf_queue = dt3155_buf_queue,
737 .buf_release = dt3155_buf_release,
738};
739
740static irqreturn_t
741dt3155_irq_handler_even(int irq, void *dev_id)
742{
743 struct dt3155_priv *ipd = dev_id;
744 struct videobuf_buffer *ivb;
745 dma_addr_t dma_addr;
746 u32 tmp;
747
748 tmp = ioread32(ipd->regs + INT_CSR) & (FLD_START | FLD_END_ODD);
749 if (!tmp)
750 return IRQ_NONE; /* not our irq */
751 if ((tmp & FLD_START) && !(tmp & FLD_END_ODD)) {
752 iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START,
753 ipd->regs + INT_CSR);
754 ipd->field_count++;
755 return IRQ_HANDLED; /* start of field irq */
756 }
757 if ((tmp & FLD_START) && (tmp & FLD_END_ODD)) {
758 if (!ipd->stats.start_before_end++)
759 printk(KERN_ERR "dt3155: irq: START before END\n");
760 }
761 /* check for corrupted fields */
762/* write_i2c_reg(ipd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE); */
763/* write_i2c_reg(ipd->regs, ODD_CSR, CSR_ERROR | CSR_DONE); */
764 tmp = ioread32(ipd->regs + CSR1) & (FLD_CRPT_EVEN | FLD_CRPT_ODD);
765 if (tmp) {
766 if (!ipd->stats.corrupted_fields++)
767 printk(KERN_ERR "dt3155: corrupted field %u\n", tmp);
768 iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN |
769 FLD_DN_ODD | FLD_DN_EVEN |
770 CAP_CONT_EVEN | CAP_CONT_ODD,
771 ipd->regs + CSR1);
772 mmiowb();
773 }
774
775 spin_lock(&ipd->lock);
776 if (ipd->curr_buf && ipd->curr_buf->state == VIDEOBUF_ACTIVE) {
777 if (waitqueue_active(&ipd->curr_buf->done)) {
778 do_gettimeofday(&ipd->curr_buf->ts);
779 ipd->curr_buf->field_count = ipd->field_count;
780 ipd->curr_buf->state = VIDEOBUF_DONE;
781 wake_up(&ipd->curr_buf->done);
782 } else {
783 ivb = ipd->curr_buf;
784 goto load_dma;
785 }
786 } else
787 goto stop_dma;
788 if (list_empty(&ipd->dmaq))
789 goto stop_dma;
790 ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), queue);
791 list_del(&ivb->queue);
792 if (ivb->state == VIDEOBUF_QUEUED) {
793 ivb->state = VIDEOBUF_ACTIVE;
794 ipd->curr_buf = ivb;
795 } else
796 goto stop_dma;
797load_dma:
798 dma_addr = videobuf_to_dma_contig(ivb);
799 iowrite32(dma_addr, ipd->regs + EVEN_DMA_START);
800 iowrite32(dma_addr + ivb->width, ipd->regs + ODD_DMA_START);
801 iowrite32(ivb->width, ipd->regs + EVEN_DMA_STRIDE);
802 iowrite32(ivb->width, ipd->regs + ODD_DMA_STRIDE);
803 mmiowb();
804 /* enable interrupts, clear all irq flags */
805 iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START |
806 FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR);
807 spin_unlock(&ipd->lock);
808 return IRQ_HANDLED;
809
810stop_dma:
811 ipd->curr_buf = NULL;
812 /* stop the board */
813 write_i2c_reg_nowait(ipd->regs, CSR2, ipd->csr2);
814 /* disable interrupts, clear all irq flags */
815 iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR);
816 spin_unlock(&ipd->lock);
817 return IRQ_HANDLED;
818}
819
820static int
821dt3155_threadfn(void *arg)
822{
823 struct dt3155_priv *pd = arg;
824 struct videobuf_buffer *vb;
825 unsigned long flags;
826
827 while (1) {
828 wait_event_interruptible(pd->do_dma,
829 kthread_should_stop() || !list_empty(&pd->dmaq));
830 if (kthread_should_stop())
831 break;
832
833 spin_lock_irqsave(&pd->lock, flags);
834 if (pd->curr_buf) /* dma is active */
835 goto done;
836 if (list_empty(&pd->dmaq)) /* no empty biffers */
837 goto done;
838 vb = list_first_entry(&pd->dmaq, typeof(*vb), queue);
839 list_del(&vb->queue);
840 if (vb->state == VIDEOBUF_QUEUED) {
841 vb->state = VIDEOBUF_ACTIVE;
842 pd->curr_buf = vb;
843 spin_unlock_irqrestore(&pd->lock, flags);
844 /* start dma */
845 dt3155_start_acq(pd);
846 continue;
847 } else
848 printk(KERN_DEBUG "%s(): This is a BUG\n", __func__);
849done:
850 spin_unlock_irqrestore(&pd->lock, flags);
851 }
852 return 0;
853}
854
855static int
856dt3155_open(struct file *filp)
857{
858 int ret = 0;
859 struct dt3155_priv *pd = video_drvdata(filp);
860
861 printk(KERN_INFO "dt3155: open(): minor: %i\n", pd->vdev->minor);
862
863 if (mutex_lock_interruptible(&pd->mux) == -EINTR)
864 return -ERESTARTSYS;
865 if (!pd->users) {
866 pd->vidq = kzalloc(sizeof(*pd->vidq), GFP_KERNEL);
867 if (!pd->vidq) {
868 printk(KERN_ERR "dt3155: error: alloc queue\n");
869 ret = -ENOMEM;
870 goto err_alloc_queue;
871 }
872 dt3155_queue_dma_contig_init(pd->vidq, &vbq_ops,
873 &pd->pdev->dev, &pd->lock,
874 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
875 sizeof(struct videobuf_buffer), pd);
876 /* disable all irqs, clear all irq flags */
877 iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD,
878 pd->regs + INT_CSR);
879 pd->irq_handler = dt3155_irq_handler_even;
880 ret = request_irq(pd->pdev->irq, pd->irq_handler,
881 IRQF_SHARED, DT3155_NAME, pd);
882 if (ret) {
883 printk(KERN_ERR "dt3155: error: request_irq\n");
884 goto err_request_irq;
885 }
886 pd->curr_buf = NULL;
887 pd->thread = kthread_run(dt3155_threadfn, pd,
888 "dt3155_thread_%i", pd->vdev->minor);
889 if (IS_ERR(pd->thread)) {
890 printk(KERN_ERR "dt3155: kthread_run() failed\n");
891 ret = PTR_ERR(pd->thread);
892 goto err_thread;
893 }
894 pd->field_count = 0;
895 }
896 pd->users++;
897 goto done;
898err_thread:
899 free_irq(pd->pdev->irq, pd);
900err_request_irq:
901 kfree(pd->vidq);
902 pd->vidq = NULL;
903err_alloc_queue:
904done:
905 mutex_unlock(&pd->mux);
906 return ret;
907}
908
909static int
910dt3155_release(struct file *filp)
911{
912 struct dt3155_priv *pd = video_drvdata(filp);
913 struct videobuf_buffer *tmp;
914 unsigned long flags;
915 int ret = 0;
916
917 printk(KERN_INFO "dt3155: release(): minor: %i\n", pd->vdev->minor);
918
919 if (mutex_lock_interruptible(&pd->mux) == -EINTR)
920 return -ERESTARTSYS;
921 pd->users--;
922 BUG_ON(pd->users < 0);
923 if (pd->acq_fp == filp) {
924 spin_lock_irqsave(&pd->lock, flags);
925 INIT_LIST_HEAD(&pd->dmaq); /* queue is emptied */
926 tmp = pd->curr_buf;
927 spin_unlock_irqrestore(&pd->lock, flags);
928 if (tmp)
929 videobuf_waiton(tmp, 0, 1); /* block, interruptible */
930 dt3155_stop_acq(pd);
931 videobuf_stop(pd->vidq);
932 pd->acq_fp = NULL;
fdd2d934 933 pd->streaming = 0;
d42bffb8
MM
934 }
935 if (!pd->users) {
936 kthread_stop(pd->thread);
937 free_irq(pd->pdev->irq, pd);
938 kfree(pd->vidq);
939 pd->vidq = NULL;
940 }
941 mutex_unlock(&pd->mux);
942 return ret;
943}
944
945static ssize_t
946dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff)
947{
948 struct dt3155_priv *pd = video_drvdata(filp);
949 int ret;
950
951 if (mutex_lock_interruptible(&pd->mux) == -EINTR)
952 return -ERESTARTSYS;
fdd2d934 953 if (!pd->acq_fp) {
d42bffb8 954 pd->acq_fp = filp;
fdd2d934
MM
955 pd->streaming = 0;
956 } else if (pd->acq_fp != filp) {
d42bffb8
MM
957 ret = -EBUSY;
958 goto done;
fdd2d934
MM
959 } else if (pd->streaming == 1) {
960 ret = -EINVAL;
961 goto done;
d42bffb8
MM
962 }
963 ret = videobuf_read_stream(pd->vidq, user, size, loff, 0,
964 filp->f_flags & O_NONBLOCK);
965done:
966 mutex_unlock(&pd->mux);
967 return ret;
968}
969
970static unsigned int
971dt3155_poll(struct file *filp, struct poll_table_struct *polltbl)
972{
973 struct dt3155_priv *pd = video_drvdata(filp);
974
975 return videobuf_poll_stream(filp, pd->vidq, polltbl);
976}
977
978static int
979dt3155_mmap(struct file *filp, struct vm_area_struct *vma)
980{
981 struct dt3155_priv *pd = video_drvdata(filp);
982
983 return videobuf_mmap_mapper(pd->vidq, vma);
984}
985
986static const struct v4l2_file_operations dt3155_fops = {
987 .owner = THIS_MODULE,
988 .open = dt3155_open,
989 .release = dt3155_release,
990 .read = dt3155_read,
991 .poll = dt3155_poll,
992 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
993 .mmap = dt3155_mmap,
994};
995
996static int
997dt3155_ioc_streamon(struct file *filp, void *p, enum v4l2_buf_type type)
998{
999 struct dt3155_priv *pd = video_drvdata(filp);
1000 int ret = -ERESTARTSYS;
1001
1002 if (mutex_lock_interruptible(&pd->mux) == -EINTR)
1003 return ret;
1004 if (!pd->acq_fp) {
1005 ret = videobuf_streamon(pd->vidq);
1006 if (ret)
1007 goto unlock;
1008 pd->acq_fp = filp;
fdd2d934 1009 pd->streaming = 1;
d42bffb8
MM
1010 wake_up_interruptible_sync(&pd->do_dma);
1011 } else if (pd->acq_fp == filp) {
fdd2d934 1012 pd->streaming = 1;
d42bffb8
MM
1013 ret = videobuf_streamon(pd->vidq);
1014 if (!ret)
1015 wake_up_interruptible_sync(&pd->do_dma);
1016 } else
1017 ret = -EBUSY;
1018unlock:
1019 mutex_unlock(&pd->mux);
1020 return ret;
1021}
1022
1023static int
1024dt3155_ioc_streamoff(struct file *filp, void *p, enum v4l2_buf_type type)
1025{
1026 struct dt3155_priv *pd = video_drvdata(filp);
1027 struct videobuf_buffer *tmp;
1028 unsigned long flags;
1029 int ret;
1030
1031 ret = videobuf_streamoff(pd->vidq);
1032 if (ret)
1033 return ret;
1034 spin_lock_irqsave(&pd->lock, flags);
1035 tmp = pd->curr_buf;
1036 spin_unlock_irqrestore(&pd->lock, flags);
1037 if (tmp)
1038 videobuf_waiton(tmp, 0, 1); /* block, interruptible */
1039 return ret;
1040}
1041
1042static int
1043dt3155_ioc_querycap(struct file *filp, void *p, struct v4l2_capability *cap)
1044{
1045 struct dt3155_priv *pd = video_drvdata(filp);
1046
1047 strcpy(cap->driver, DT3155_NAME);
1048 strcpy(cap->card, DT3155_NAME " frame grabber");
1049 sprintf(cap->bus_info, "PCI:%s", pci_name(pd->pdev));
1050 cap->version =
1051 KERNEL_VERSION(DT3155_VER_MAJ, DT3155_VER_MIN, DT3155_VER_EXT);
1052 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
fdd2d934 1053 V4L2_CAP_STREAMING |
d42bffb8 1054 V4L2_CAP_READWRITE;
d42bffb8
MM
1055 return 0;
1056}
1057
1058static int
1059dt3155_ioc_enum_fmt_vid_cap(struct file *filp, void *p, struct v4l2_fmtdesc *f)
1060{
1061 if (f->index >= NUM_OF_FORMATS)
1062 return -EINVAL;
1063 *f = frame_std[f->index];
1064 return 0;
1065}
1066
1067static int
1068dt3155_ioc_g_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
1069{
1070 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1071 return -EINVAL;
1072 f->fmt.pix.width = img_width;
1073 f->fmt.pix.height = img_height;
1074 f->fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;
1075 f->fmt.pix.field = V4L2_FIELD_NONE;
1076 f->fmt.pix.bytesperline = f->fmt.pix.width;
1077 f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height;
1078 f->fmt.pix.colorspace = 0;
1079 f->fmt.pix.priv = 0;
1080 return 0;
1081}
1082
1083static int
1084dt3155_ioc_try_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
1085{
1086 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1087 return -EINVAL;
1088 if (f->fmt.pix.width == img_width &&
1089 f->fmt.pix.height == img_height &&
1090 f->fmt.pix.pixelformat == V4L2_PIX_FMT_GREY &&
1091 f->fmt.pix.field == V4L2_FIELD_NONE &&
1092 f->fmt.pix.bytesperline == f->fmt.pix.width &&
1093 f->fmt.pix.sizeimage == f->fmt.pix.width * f->fmt.pix.height)
1094 return 0;
1095 else
1096 return -EINVAL;
1097}
1098
1099static int
1100dt3155_ioc_s_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
1101{
fdd2d934
MM
1102 struct dt3155_priv *pd = video_drvdata(filp);
1103 int ret = -ERESTARTSYS;
1104
1105 if (mutex_lock_interruptible(&pd->mux) == -EINTR)
1106 return ret;
1107 if (!pd->acq_fp) {
1108 pd->acq_fp = filp;
1109 pd->streaming = 0;
1110 } else if (pd->acq_fp != filp) {
1111 ret = -EBUSY;
1112 goto done;
1113 }
1114/* FIXME: we don't change the format for now
1115 if (pd->vidq->streaming || pd->vidq->reading || pd->curr_buff) {
1116 ret = -EBUSY;
1117 goto done;
1118 }
1119*/
1120 ret = dt3155_ioc_g_fmt_vid_cap(filp, p, f);
1121done:
1122 mutex_unlock(&pd->mux);
1123 return ret;
d42bffb8
MM
1124}
1125
1126static int
1127dt3155_ioc_reqbufs(struct file *filp, void *p, struct v4l2_requestbuffers *b)
1128{
1129 struct dt3155_priv *pd = video_drvdata(filp);
1130 struct videobuf_queue *q = pd->vidq;
fdd2d934 1131 int ret = -ERESTARTSYS;
d42bffb8
MM
1132
1133 if (b->memory != V4L2_MEMORY_MMAP)
1134 return -EINVAL;
fdd2d934
MM
1135 if (mutex_lock_interruptible(&pd->mux) == -EINTR)
1136 return ret;
1137 if (!pd->acq_fp)
1138 pd->acq_fp = filp;
1139 else if (pd->acq_fp != filp) {
1140 ret = -EBUSY;
1141 goto done;
1142 }
1143 pd->streaming = 1;
1144 ret = 0;
1145done:
1146 mutex_unlock(&pd->mux);
1147 if (ret)
1148 return ret;
d42bffb8 1149 if (b->count)
fdd2d934 1150 ret = videobuf_reqbufs(q, b);
d42bffb8
MM
1151 else { /* FIXME: is it necessary? */
1152 printk(KERN_DEBUG "dt3155: request to free buffers\n");
fdd2d934
MM
1153 /* ret = videobuf_mmap_free(q); */
1154 ret = dt3155_ioc_streamoff(filp, p,
1155 V4L2_BUF_TYPE_VIDEO_CAPTURE);
d42bffb8 1156 }
fdd2d934 1157 return ret;
d42bffb8
MM
1158}
1159
1160static int
1161dt3155_ioc_querybuf(struct file *filp, void *p, struct v4l2_buffer *b)
1162{
1163 struct dt3155_priv *pd = video_drvdata(filp);
1164 struct videobuf_queue *q = pd->vidq;
1165
1166 return videobuf_querybuf(q, b);
1167}
1168
1169static int
1170dt3155_ioc_qbuf(struct file *filp, void *p, struct v4l2_buffer *b)
1171{
1172 struct dt3155_priv *pd = video_drvdata(filp);
1173 struct videobuf_queue *q = pd->vidq;
fdd2d934 1174 int ret;
d42bffb8 1175
fdd2d934
MM
1176 ret = videobuf_qbuf(q, b);
1177 if (ret)
1178 return ret;
1179 return videobuf_querybuf(q, b);
d42bffb8
MM
1180}
1181
1182static int
1183dt3155_ioc_dqbuf(struct file *filp, void *p, struct v4l2_buffer *b)
1184{
1185 struct dt3155_priv *pd = video_drvdata(filp);
1186 struct videobuf_queue *q = pd->vidq;
1187
1188 return videobuf_dqbuf(q, b, filp->f_flags & O_NONBLOCK);
1189}
1190
1191static int
1192dt3155_ioc_querystd(struct file *filp, void *p, v4l2_std_id *norm)
1193{
1194 *norm = DT3155_CURRENT_NORM;
1195 return 0;
1196}
1197
1198static int
1199dt3155_ioc_g_std(struct file *filp, void *p, v4l2_std_id *norm)
1200{
1201 *norm = DT3155_CURRENT_NORM;
1202 return 0;
1203}
1204
1205static int
1206dt3155_ioc_s_std(struct file *filp, void *p, v4l2_std_id *norm)
1207{
1208 if (*norm & DT3155_CURRENT_NORM)
1209 return 0;
1210 return -EINVAL;
1211}
1212
1213static int
1214dt3155_ioc_enum_input(struct file *filp, void *p, struct v4l2_input *input)
1215{
1216 if (input->index)
1217 return -EINVAL;
1218 strcpy(input->name, "Coax in");
1219 input->type = V4L2_INPUT_TYPE_CAMERA;
fdd2d934
MM
1220 /*
1221 * FIXME: input->std = 0 according to v4l2 API
1222 * VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_QUERYSTD and VIDIOC_ENUMSTD
1223 * should return -EINVAL
1224 */
1225 input->std = DT3155_CURRENT_NORM;
d42bffb8
MM
1226 input->status = 0;/* FIXME: add sync detection & V4L2_IN_ST_NO_H_LOCK */
1227 return 0;
1228}
1229
1230static int
1231dt3155_ioc_g_input(struct file *filp, void *p, unsigned int *i)
1232{
1233 *i = 0;
1234 return 0;
1235}
1236
1237static int
1238dt3155_ioc_s_input(struct file *filp, void *p, unsigned int i)
1239{
1240 if (i)
1241 return -EINVAL;
1242 return 0;
1243}
1244
1245static int
1246dt3155_ioc_g_parm(struct file *filp, void *p, struct v4l2_streamparm *parms)
1247{
1248 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1249 return -EINVAL;
1250 parms->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1251 parms->parm.capture.capturemode = 0;
1252 parms->parm.capture.timeperframe.numerator = 1001;
1253 parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000;
1254 parms->parm.capture.extendedmode = 0;
fdd2d934 1255 parms->parm.capture.readbuffers = 1; /* FIXME: 2 buffers? */
d42bffb8
MM
1256 return 0;
1257}
1258
1259static int
1260dt3155_ioc_s_parm(struct file *filp, void *p, struct v4l2_streamparm *parms)
1261{
1262 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1263 return -EINVAL;
1264 parms->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1265 parms->parm.capture.capturemode = 0;
1266 parms->parm.capture.timeperframe.numerator = 1001;
1267 parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000;
1268 parms->parm.capture.extendedmode = 0;
fdd2d934 1269 parms->parm.capture.readbuffers = 1; /* FIXME: 2 buffers? */
d42bffb8
MM
1270 return 0;
1271}
1272
1273static const struct v4l2_ioctl_ops dt3155_ioctl_ops = {
1274 .vidioc_streamon = dt3155_ioc_streamon,
1275 .vidioc_streamoff = dt3155_ioc_streamoff,
1276 .vidioc_querycap = dt3155_ioc_querycap,
1277/*
1278 .vidioc_g_priority = dt3155_ioc_g_priority,
1279 .vidioc_s_priority = dt3155_ioc_s_priority,
1280*/
1281 .vidioc_enum_fmt_vid_cap = dt3155_ioc_enum_fmt_vid_cap,
1282 .vidioc_try_fmt_vid_cap = dt3155_ioc_try_fmt_vid_cap,
1283 .vidioc_g_fmt_vid_cap = dt3155_ioc_g_fmt_vid_cap,
1284 .vidioc_s_fmt_vid_cap = dt3155_ioc_s_fmt_vid_cap,
1285 .vidioc_reqbufs = dt3155_ioc_reqbufs,
1286 .vidioc_querybuf = dt3155_ioc_querybuf,
1287 .vidioc_qbuf = dt3155_ioc_qbuf,
1288 .vidioc_dqbuf = dt3155_ioc_dqbuf,
1289 .vidioc_querystd = dt3155_ioc_querystd,
1290 .vidioc_g_std = dt3155_ioc_g_std,
1291 .vidioc_s_std = dt3155_ioc_s_std,
1292 .vidioc_enum_input = dt3155_ioc_enum_input,
1293 .vidioc_g_input = dt3155_ioc_g_input,
1294 .vidioc_s_input = dt3155_ioc_s_input,
1295/*
1296 .vidioc_queryctrl = dt3155_ioc_queryctrl,
1297 .vidioc_g_ctrl = dt3155_ioc_g_ctrl,
1298 .vidioc_s_ctrl = dt3155_ioc_s_ctrl,
1299 .vidioc_querymenu = dt3155_ioc_querymenu,
1300 .vidioc_g_ext_ctrls = dt3155_ioc_g_ext_ctrls,
1301 .vidioc_s_ext_ctrls = dt3155_ioc_s_ext_ctrls,
1302*/
1303 .vidioc_g_parm = dt3155_ioc_g_parm,
1304 .vidioc_s_parm = dt3155_ioc_s_parm,
1305/*
1306 .vidioc_cropcap = dt3155_ioc_cropcap,
1307 .vidioc_g_crop = dt3155_ioc_g_crop,
1308 .vidioc_s_crop = dt3155_ioc_s_crop,
1309 .vidioc_enum_framesizes = dt3155_ioc_enum_framesizes,
1310 .vidioc_enum_frameintervals = dt3155_ioc_enum_frameintervals,
1311#ifdef CONFIG_VIDEO_V4L1_COMPAT
1312 .vidiocgmbuf = iocgmbuf,
1313#endif
1314*/
1315};
1316
1317static int __devinit
1318dt3155_init_board(struct pci_dev *dev)
1319{
1320 int i;
1321 u8 tmp;
1322 struct dt3155_buf *buf;
1323 struct dt3155_priv *pd = pci_get_drvdata(dev);
1324 pci_set_master(dev); /* dt3155 needs it */
1325
1326 /* resetting the adapter */
1327 iowrite32(FLD_CRPT_ODD | FLD_CRPT_EVEN | FLD_DN_ODD | FLD_DN_EVEN,
1328 pd->regs + CSR1);
1329 mmiowb();
1330 msleep(10);
1331
1332 /* initializing adaper registers */
1333 iowrite32(FIFO_EN | SRST, pd->regs + CSR1);
1334 mmiowb();
1335 iowrite32(0xEEEEEE01, pd->regs + EVEN_PIXEL_FMT);
1336 iowrite32(0xEEEEEE01, pd->regs + ODD_PIXEL_FMT);
1337 iowrite32(0x00000020, pd->regs + FIFO_TRIGER);
1338 iowrite32(0x00000103, pd->regs + XFER_MODE);
1339 iowrite32(0, pd->regs + RETRY_WAIT_CNT);
1340 iowrite32(0, pd->regs + INT_CSR);
1341 iowrite32(1, pd->regs + EVEN_FLD_MASK);
1342 iowrite32(1, pd->regs + ODD_FLD_MASK);
1343 iowrite32(0, pd->regs + MASK_LENGTH);
1344 iowrite32(0x0005007C, pd->regs + FIFO_FLAG_CNT);
1345 iowrite32(0x01010101, pd->regs + IIC_CLK_DUR);
1346 mmiowb();
1347
1348 /* verifying that we have a DT3155 board (not just a SAA7116 chip) */
1349 read_i2c_reg(pd->regs, DT_ID, &tmp);
1350 if (tmp != DT3155_ID)
1351 return -ENODEV;
1352
1353 /* initialize AD LUT */
1354 write_i2c_reg(pd->regs, AD_ADDR, 0);
1355 for (i = 0; i < 256; i++)
1356 write_i2c_reg(pd->regs, AD_LUT, i);
1357
1358 /* initialize ADC references */
1359 /* FIXME: pos_ref & neg_ref depend on VT_50HZ */
1360 write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG);
1361 write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3);
1362 write_i2c_reg(pd->regs, AD_ADDR, AD_POS_REF);
1363 write_i2c_reg(pd->regs, AD_CMD, 34);
1364 write_i2c_reg(pd->regs, AD_ADDR, AD_NEG_REF);
1365 write_i2c_reg(pd->regs, AD_CMD, 0);
1366
1367 /* initialize PM LUT */
1368 write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM);
1369 for (i = 0; i < 256; i++) {
1370 write_i2c_reg(pd->regs, PM_LUT_ADDR, i);
1371 write_i2c_reg(pd->regs, PM_LUT_DATA, i);
1372 }
1373 write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM | PM_LUT_SEL);
1374 for (i = 0; i < 256; i++) {
1375 write_i2c_reg(pd->regs, PM_LUT_ADDR, i);
1376 write_i2c_reg(pd->regs, PM_LUT_DATA, i);
1377 }
1378 write_i2c_reg(pd->regs, CONFIG, pd->config); /* ACQ_MODE_EVEN */
1379
1380 /* select chanel 1 for input and set sync level */
1381 write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG);
1382 write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3);
1383
1384 /* allocate and pci_map memory, and initialize the DMA machine */
1385 buf = dt3155_get_buf(dt3155_free_bufs);
1386 if (!buf) {
1387 printk(KERN_ERR "dt3155: dt3155_get_buf "
1388 "(in dt3155_init_board) failed\n");
1389 return -ENOMEM;
1390 }
1391 buf->dma = pci_map_single(dev, buf->cpu,
1392 DT3155_BUF_SIZE, PCI_DMA_FROMDEVICE);
1393 if (pci_dma_mapping_error(dev, buf->dma)) {
1394 printk(KERN_ERR "dt3155: pci_map_single failed\n");
1395 dt3155_put_buf(buf, dt3155_free_bufs);
1396 return -ENOMEM;
1397 }
1398 iowrite32(buf->dma, pd->regs + EVEN_DMA_START);
1399 iowrite32(buf->dma, pd->regs + ODD_DMA_START);
1400 iowrite32(0, pd->regs + EVEN_DMA_STRIDE);
1401 iowrite32(0, pd->regs + ODD_DMA_STRIDE);
1402
1403 /* Perform a pseudo even field acquire */
1404 iowrite32(FIFO_EN | SRST | CAP_CONT_ODD, pd->regs + CSR1);
1405 write_i2c_reg(pd->regs, CSR2, pd->csr2 | SYNC_SNTL);
1406 write_i2c_reg(pd->regs, CONFIG, pd->config);
1407 write_i2c_reg(pd->regs, EVEN_CSR, CSR_SNGL);
1408 write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | SYNC_SNTL);
1409 msleep(100);
1410 read_i2c_reg(pd->regs, CSR2, &tmp);
1411 write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_SNGL | CSR_DONE);
1412 write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_SNGL | CSR_DONE);
1413 write_i2c_reg(pd->regs, CSR2, pd->csr2);
1414 iowrite32(FIFO_EN | SRST | FLD_DN_EVEN | FLD_DN_ODD, pd->regs + CSR1);
1415
1416 /* pci_unmap and deallocate memory */
1417 pci_unmap_single(dev, buf->dma, DT3155_BUF_SIZE, PCI_DMA_FROMDEVICE);
1418 dt3155_put_buf(buf, dt3155_free_bufs);
1419 if (tmp & BUSY_EVEN) {
1420 printk(KERN_ERR "dt3155: BUSY_EVEN not cleared\n");
1421 return -EIO;
1422 }
1423 return 0;
1424}
1425
1426static struct video_device dt3155_vdev = {
1427 .name = DT3155_NAME,
1428 .fops = &dt3155_fops,
1429 .ioctl_ops = &dt3155_ioctl_ops,
1430 .minor = -1,
1431 .release = video_device_release,
fdd2d934 1432 .tvnorms = DT3155_CURRENT_NORM,
d42bffb8
MM
1433 .current_norm = DT3155_CURRENT_NORM,
1434};
1435
1436static int __devinit
1437dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id)
1438{
1439 int err = -ENODEV;
1440 struct dt3155_priv *pd;
1441
1442 printk(KERN_INFO "dt3155: probe()\n");
1443 if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
1444 printk(KERN_ERR "dt3155: cannot set dma_mask\n");
1445 return -ENODEV;
1446 }
1447 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
1448 if (!pd) {
1449 printk(KERN_ERR "dt3155: cannot allocate dt3155_priv\n");
1450 return -ENOMEM;
1451 }
1452 pd->vdev = video_device_alloc();
1453 if (!pd->vdev) {
1454 printk(KERN_ERR "dt3155: cannot allocate vdp structure\n");
1455 goto err_video_device_alloc;
1456 }
1457 *pd->vdev = dt3155_vdev;
1458 pci_set_drvdata(dev, pd); /* for use in dt3155_remove() */
1459 video_set_drvdata(pd->vdev, pd); /* for use in video_fops */
1460 pd->users = 0;
1461 pd->acq_fp = NULL;
1462 pd->pdev = dev;
1463 INIT_LIST_HEAD(&pd->dmaq);
1464 init_waitqueue_head(&pd->do_dma);
1465 mutex_init(&pd->mux);
1466 pd->csr2 = csr2_init;
1467 pd->config = config_init;
1468 err = pci_enable_device(pd->pdev);
1469 if (err) {
1470 printk(KERN_ERR "dt3155: pci_dev not enabled\n");
1471 goto err_enable_dev;
1472 }
1473 err = pci_request_region(pd->pdev, 0, pci_name(pd->pdev));
1474 if (err)
1475 goto err_req_region;
1476 pd->regs = pci_iomap(pd->pdev, 0, pci_resource_len(pd->pdev, 0));
1477 if (!pd->regs) {
1478 err = -ENOMEM;
1479 printk(KERN_ERR "dt3155: pci_iomap failed\n");
1480 goto err_pci_iomap;
1481 }
1482 err = dt3155_init_board(pd->pdev);
1483 if (err) {
1484 printk(KERN_ERR "dt3155: dt3155_init_board failed\n");
1485 goto err_init_board;
1486 }
1487 err = video_register_device(pd->vdev, VFL_TYPE_GRABBER, -1);
1488 if (err) {
1489 printk(KERN_ERR "dt3155: Cannot register video device\n");
1490 goto err_init_board;
1491 }
1492 printk(KERN_INFO "dt3155: /dev/video%i is ready\n", pd->vdev->minor);
1493 return 0; /* success */
1494
1495err_init_board:
1496 pci_iounmap(pd->pdev, pd->regs);
1497err_pci_iomap:
1498 pci_release_region(pd->pdev, 0);
1499err_req_region:
1500 pci_disable_device(pd->pdev);
1501err_enable_dev:
1502 video_device_release(pd->vdev);
1503err_video_device_alloc:
1504 kfree(pd);
1505 return err;
1506}
1507
1508static void __devexit
1509dt3155_remove(struct pci_dev *dev)
1510{
1511 struct dt3155_priv *pd = pci_get_drvdata(dev);
1512
1513 printk(KERN_INFO "dt3155: remove()\n");
1514 video_unregister_device(pd->vdev);
1515 pci_iounmap(dev, pd->regs);
1516 pci_release_region(pd->pdev, 0);
1517 pci_disable_device(pd->pdev);
1518 /*
1519 * video_device_release() is invoked automatically
1520 * see: struct video_device dt3155_vdev
1521 */
1522 kfree(pd);
1523}
1524
1525static DEFINE_PCI_DEVICE_TABLE(pci_ids) = {
1526 { PCI_DEVICE(DT3155_VENDOR_ID, DT3155_DEVICE_ID) },
1527 { 0, /* zero marks the end */ },
1528};
1529MODULE_DEVICE_TABLE(pci, pci_ids);
1530
1531static struct pci_driver pci_driver = {
1532 .name = DT3155_NAME,
1533 .id_table = pci_ids,
1534 .probe = dt3155_probe,
1535 .remove = __devexit_p(dt3155_remove),
1536};
1537
1538static int __init
1539dt3155_init_module(void)
1540{
1541 int err;
1542
1543 printk(KERN_INFO "dt3155: ==================\n");
1544 printk(KERN_INFO "dt3155: init()\n");
1545 dt3155_chunks = dt3155_init_chunks_fifo();
1546 if (!dt3155_chunks) {
1547 err = -ENOMEM;
1548 printk(KERN_ERR "dt3155: cannot init dt3155_chunks_fifo\n");
1549 goto err_init_chunks_fifo;
1550 }
1551 dt3155_free_bufs = dt3155_init_ibufs_fifo(dt3155_chunks,
1552 DT3155_BUF_SIZE);
1553 if (!dt3155_free_bufs) {
1554 err = -ENOMEM;
1555 printk(KERN_ERR "dt3155: cannot dt3155_init_ibufs_fifo\n");
1556 goto err_init_ibufs_fifo;
1557 }
1558 dt3155_alloc_bufs = dt3155_init_fifo();
1559 if (!dt3155_alloc_bufs) {
1560 err = -ENOMEM;
1561 printk(KERN_ERR "dt3155: cannot dt3155_init_fifo\n");
1562 goto err_init_fifo;
1563 }
1564 err = pci_register_driver(&pci_driver);
1565 if (err) {
1566 printk(KERN_ERR "dt3155: cannot register pci_driver\n");
1567 goto err_register_driver;
1568 }
1569 return 0; /* succes */
1570err_register_driver:
1571 dt3155_free_fifo(dt3155_alloc_bufs);
1572err_init_fifo:
1573 dt3155_free_ibufs_fifo(dt3155_free_bufs);
1574err_init_ibufs_fifo:
1575 dt3155_free_chunks_fifo(dt3155_chunks);
1576err_init_chunks_fifo:
1577 return err;
1578}
1579
1580static void __exit
1581dt3155_exit_module(void)
1582{
1583 pci_unregister_driver(&pci_driver);
1584 dt3155_free_fifo(dt3155_alloc_bufs);
1585 dt3155_free_ibufs_fifo(dt3155_free_bufs);
1586 dt3155_free_chunks_fifo(dt3155_chunks);
1587 printk(KERN_INFO "dt3155: exit()\n");
1588 printk(KERN_INFO "dt3155: ==================\n");
1589}
1590
1591module_init(dt3155_init_module);
1592module_exit(dt3155_exit_module);
1593
1594MODULE_DESCRIPTION("video4linux pci-driver for dt3155 frame grabber");
1595MODULE_AUTHOR("Marin Mitov <mitov@issp.bas.bg>");
1596MODULE_VERSION(DT3155_VERSION);
1597MODULE_LICENSE("GPL");
This page took 0.091353 seconds and 5 git commands to generate.