Staging: rtl8187se: fixed C99 comments style issues in r8180_core.c
[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;
933 }
934 if (!pd->users) {
935 kthread_stop(pd->thread);
936 free_irq(pd->pdev->irq, pd);
937 kfree(pd->vidq);
938 pd->vidq = NULL;
939 }
940 mutex_unlock(&pd->mux);
941 return ret;
942}
943
944static ssize_t
945dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff)
946{
947 struct dt3155_priv *pd = video_drvdata(filp);
948 int ret;
949
950 if (mutex_lock_interruptible(&pd->mux) == -EINTR)
951 return -ERESTARTSYS;
952 if (!pd->acq_fp)
953 pd->acq_fp = filp;
954 else if (pd->acq_fp != filp) {
955 ret = -EBUSY;
956 goto done;
957 }
958 ret = videobuf_read_stream(pd->vidq, user, size, loff, 0,
959 filp->f_flags & O_NONBLOCK);
960done:
961 mutex_unlock(&pd->mux);
962 return ret;
963}
964
965static unsigned int
966dt3155_poll(struct file *filp, struct poll_table_struct *polltbl)
967{
968 struct dt3155_priv *pd = video_drvdata(filp);
969
970 return videobuf_poll_stream(filp, pd->vidq, polltbl);
971}
972
973static int
974dt3155_mmap(struct file *filp, struct vm_area_struct *vma)
975{
976 struct dt3155_priv *pd = video_drvdata(filp);
977
978 return videobuf_mmap_mapper(pd->vidq, vma);
979}
980
981static const struct v4l2_file_operations dt3155_fops = {
982 .owner = THIS_MODULE,
983 .open = dt3155_open,
984 .release = dt3155_release,
985 .read = dt3155_read,
986 .poll = dt3155_poll,
987 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
988 .mmap = dt3155_mmap,
989};
990
991static int
992dt3155_ioc_streamon(struct file *filp, void *p, enum v4l2_buf_type type)
993{
994 struct dt3155_priv *pd = video_drvdata(filp);
995 int ret = -ERESTARTSYS;
996
997 if (mutex_lock_interruptible(&pd->mux) == -EINTR)
998 return ret;
999 if (!pd->acq_fp) {
1000 ret = videobuf_streamon(pd->vidq);
1001 if (ret)
1002 goto unlock;
1003 pd->acq_fp = filp;
1004 wake_up_interruptible_sync(&pd->do_dma);
1005 } else if (pd->acq_fp == filp) {
1006 ret = videobuf_streamon(pd->vidq);
1007 if (!ret)
1008 wake_up_interruptible_sync(&pd->do_dma);
1009 } else
1010 ret = -EBUSY;
1011unlock:
1012 mutex_unlock(&pd->mux);
1013 return ret;
1014}
1015
1016static int
1017dt3155_ioc_streamoff(struct file *filp, void *p, enum v4l2_buf_type type)
1018{
1019 struct dt3155_priv *pd = video_drvdata(filp);
1020 struct videobuf_buffer *tmp;
1021 unsigned long flags;
1022 int ret;
1023
1024 ret = videobuf_streamoff(pd->vidq);
1025 if (ret)
1026 return ret;
1027 spin_lock_irqsave(&pd->lock, flags);
1028 tmp = pd->curr_buf;
1029 spin_unlock_irqrestore(&pd->lock, flags);
1030 if (tmp)
1031 videobuf_waiton(tmp, 0, 1); /* block, interruptible */
1032 return ret;
1033}
1034
1035static int
1036dt3155_ioc_querycap(struct file *filp, void *p, struct v4l2_capability *cap)
1037{
1038 struct dt3155_priv *pd = video_drvdata(filp);
1039
1040 strcpy(cap->driver, DT3155_NAME);
1041 strcpy(cap->card, DT3155_NAME " frame grabber");
1042 sprintf(cap->bus_info, "PCI:%s", pci_name(pd->pdev));
1043 cap->version =
1044 KERNEL_VERSION(DT3155_VER_MAJ, DT3155_VER_MIN, DT3155_VER_EXT);
1045 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1046#ifdef CONFIG_DT3155_STREAMING
1047 V4L2_CAP_STREAMING;
1048#else
1049 V4L2_CAP_READWRITE;
1050#endif
1051 return 0;
1052}
1053
1054static int
1055dt3155_ioc_enum_fmt_vid_cap(struct file *filp, void *p, struct v4l2_fmtdesc *f)
1056{
1057 if (f->index >= NUM_OF_FORMATS)
1058 return -EINVAL;
1059 *f = frame_std[f->index];
1060 return 0;
1061}
1062
1063static int
1064dt3155_ioc_g_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
1065{
1066 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1067 return -EINVAL;
1068 f->fmt.pix.width = img_width;
1069 f->fmt.pix.height = img_height;
1070 f->fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;
1071 f->fmt.pix.field = V4L2_FIELD_NONE;
1072 f->fmt.pix.bytesperline = f->fmt.pix.width;
1073 f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height;
1074 f->fmt.pix.colorspace = 0;
1075 f->fmt.pix.priv = 0;
1076 return 0;
1077}
1078
1079static int
1080dt3155_ioc_try_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
1081{
1082 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1083 return -EINVAL;
1084 if (f->fmt.pix.width == img_width &&
1085 f->fmt.pix.height == img_height &&
1086 f->fmt.pix.pixelformat == V4L2_PIX_FMT_GREY &&
1087 f->fmt.pix.field == V4L2_FIELD_NONE &&
1088 f->fmt.pix.bytesperline == f->fmt.pix.width &&
1089 f->fmt.pix.sizeimage == f->fmt.pix.width * f->fmt.pix.height)
1090 return 0;
1091 else
1092 return -EINVAL;
1093}
1094
1095static int
1096dt3155_ioc_s_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
1097{
1098 return dt3155_ioc_g_fmt_vid_cap(filp, p, f);
1099}
1100
1101static int
1102dt3155_ioc_reqbufs(struct file *filp, void *p, struct v4l2_requestbuffers *b)
1103{
1104 struct dt3155_priv *pd = video_drvdata(filp);
1105 struct videobuf_queue *q = pd->vidq;
1106
1107 if (b->memory != V4L2_MEMORY_MMAP)
1108 return -EINVAL;
1109 if (b->count)
1110 return videobuf_reqbufs(q, b);
1111 else { /* FIXME: is it necessary? */
1112 printk(KERN_DEBUG "dt3155: request to free buffers\n");
1113 return videobuf_mmap_free(q);
1114 }
1115}
1116
1117static int
1118dt3155_ioc_querybuf(struct file *filp, void *p, struct v4l2_buffer *b)
1119{
1120 struct dt3155_priv *pd = video_drvdata(filp);
1121 struct videobuf_queue *q = pd->vidq;
1122
1123 return videobuf_querybuf(q, b);
1124}
1125
1126static int
1127dt3155_ioc_qbuf(struct file *filp, void *p, struct v4l2_buffer *b)
1128{
1129 struct dt3155_priv *pd = video_drvdata(filp);
1130 struct videobuf_queue *q = pd->vidq;
1131
1132 return videobuf_qbuf(q, b);
1133}
1134
1135static int
1136dt3155_ioc_dqbuf(struct file *filp, void *p, struct v4l2_buffer *b)
1137{
1138 struct dt3155_priv *pd = video_drvdata(filp);
1139 struct videobuf_queue *q = pd->vidq;
1140
1141 return videobuf_dqbuf(q, b, filp->f_flags & O_NONBLOCK);
1142}
1143
1144static int
1145dt3155_ioc_querystd(struct file *filp, void *p, v4l2_std_id *norm)
1146{
1147 *norm = DT3155_CURRENT_NORM;
1148 return 0;
1149}
1150
1151static int
1152dt3155_ioc_g_std(struct file *filp, void *p, v4l2_std_id *norm)
1153{
1154 *norm = DT3155_CURRENT_NORM;
1155 return 0;
1156}
1157
1158static int
1159dt3155_ioc_s_std(struct file *filp, void *p, v4l2_std_id *norm)
1160{
1161 if (*norm & DT3155_CURRENT_NORM)
1162 return 0;
1163 return -EINVAL;
1164}
1165
1166static int
1167dt3155_ioc_enum_input(struct file *filp, void *p, struct v4l2_input *input)
1168{
1169 if (input->index)
1170 return -EINVAL;
1171 strcpy(input->name, "Coax in");
1172 input->type = V4L2_INPUT_TYPE_CAMERA;
1173 input->std = V4L2_STD_ALL;
1174 input->status = 0;/* FIXME: add sync detection & V4L2_IN_ST_NO_H_LOCK */
1175 return 0;
1176}
1177
1178static int
1179dt3155_ioc_g_input(struct file *filp, void *p, unsigned int *i)
1180{
1181 *i = 0;
1182 return 0;
1183}
1184
1185static int
1186dt3155_ioc_s_input(struct file *filp, void *p, unsigned int i)
1187{
1188 if (i)
1189 return -EINVAL;
1190 return 0;
1191}
1192
1193static int
1194dt3155_ioc_g_parm(struct file *filp, void *p, struct v4l2_streamparm *parms)
1195{
1196 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1197 return -EINVAL;
1198 parms->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1199 parms->parm.capture.capturemode = 0;
1200 parms->parm.capture.timeperframe.numerator = 1001;
1201 parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000;
1202 parms->parm.capture.extendedmode = 0;
1203 parms->parm.capture.readbuffers = 1;
1204 return 0;
1205}
1206
1207static int
1208dt3155_ioc_s_parm(struct file *filp, void *p, struct v4l2_streamparm *parms)
1209{
1210 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1211 return -EINVAL;
1212 parms->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1213 parms->parm.capture.capturemode = 0;
1214 parms->parm.capture.timeperframe.numerator = 1001;
1215 parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000;
1216 parms->parm.capture.extendedmode = 0;
1217 parms->parm.capture.readbuffers = 1;
1218 return 0;
1219}
1220
1221static const struct v4l2_ioctl_ops dt3155_ioctl_ops = {
1222 .vidioc_streamon = dt3155_ioc_streamon,
1223 .vidioc_streamoff = dt3155_ioc_streamoff,
1224 .vidioc_querycap = dt3155_ioc_querycap,
1225/*
1226 .vidioc_g_priority = dt3155_ioc_g_priority,
1227 .vidioc_s_priority = dt3155_ioc_s_priority,
1228*/
1229 .vidioc_enum_fmt_vid_cap = dt3155_ioc_enum_fmt_vid_cap,
1230 .vidioc_try_fmt_vid_cap = dt3155_ioc_try_fmt_vid_cap,
1231 .vidioc_g_fmt_vid_cap = dt3155_ioc_g_fmt_vid_cap,
1232 .vidioc_s_fmt_vid_cap = dt3155_ioc_s_fmt_vid_cap,
1233 .vidioc_reqbufs = dt3155_ioc_reqbufs,
1234 .vidioc_querybuf = dt3155_ioc_querybuf,
1235 .vidioc_qbuf = dt3155_ioc_qbuf,
1236 .vidioc_dqbuf = dt3155_ioc_dqbuf,
1237 .vidioc_querystd = dt3155_ioc_querystd,
1238 .vidioc_g_std = dt3155_ioc_g_std,
1239 .vidioc_s_std = dt3155_ioc_s_std,
1240 .vidioc_enum_input = dt3155_ioc_enum_input,
1241 .vidioc_g_input = dt3155_ioc_g_input,
1242 .vidioc_s_input = dt3155_ioc_s_input,
1243/*
1244 .vidioc_queryctrl = dt3155_ioc_queryctrl,
1245 .vidioc_g_ctrl = dt3155_ioc_g_ctrl,
1246 .vidioc_s_ctrl = dt3155_ioc_s_ctrl,
1247 .vidioc_querymenu = dt3155_ioc_querymenu,
1248 .vidioc_g_ext_ctrls = dt3155_ioc_g_ext_ctrls,
1249 .vidioc_s_ext_ctrls = dt3155_ioc_s_ext_ctrls,
1250*/
1251 .vidioc_g_parm = dt3155_ioc_g_parm,
1252 .vidioc_s_parm = dt3155_ioc_s_parm,
1253/*
1254 .vidioc_cropcap = dt3155_ioc_cropcap,
1255 .vidioc_g_crop = dt3155_ioc_g_crop,
1256 .vidioc_s_crop = dt3155_ioc_s_crop,
1257 .vidioc_enum_framesizes = dt3155_ioc_enum_framesizes,
1258 .vidioc_enum_frameintervals = dt3155_ioc_enum_frameintervals,
1259#ifdef CONFIG_VIDEO_V4L1_COMPAT
1260 .vidiocgmbuf = iocgmbuf,
1261#endif
1262*/
1263};
1264
1265static int __devinit
1266dt3155_init_board(struct pci_dev *dev)
1267{
1268 int i;
1269 u8 tmp;
1270 struct dt3155_buf *buf;
1271 struct dt3155_priv *pd = pci_get_drvdata(dev);
1272 pci_set_master(dev); /* dt3155 needs it */
1273
1274 /* resetting the adapter */
1275 iowrite32(FLD_CRPT_ODD | FLD_CRPT_EVEN | FLD_DN_ODD | FLD_DN_EVEN,
1276 pd->regs + CSR1);
1277 mmiowb();
1278 msleep(10);
1279
1280 /* initializing adaper registers */
1281 iowrite32(FIFO_EN | SRST, pd->regs + CSR1);
1282 mmiowb();
1283 iowrite32(0xEEEEEE01, pd->regs + EVEN_PIXEL_FMT);
1284 iowrite32(0xEEEEEE01, pd->regs + ODD_PIXEL_FMT);
1285 iowrite32(0x00000020, pd->regs + FIFO_TRIGER);
1286 iowrite32(0x00000103, pd->regs + XFER_MODE);
1287 iowrite32(0, pd->regs + RETRY_WAIT_CNT);
1288 iowrite32(0, pd->regs + INT_CSR);
1289 iowrite32(1, pd->regs + EVEN_FLD_MASK);
1290 iowrite32(1, pd->regs + ODD_FLD_MASK);
1291 iowrite32(0, pd->regs + MASK_LENGTH);
1292 iowrite32(0x0005007C, pd->regs + FIFO_FLAG_CNT);
1293 iowrite32(0x01010101, pd->regs + IIC_CLK_DUR);
1294 mmiowb();
1295
1296 /* verifying that we have a DT3155 board (not just a SAA7116 chip) */
1297 read_i2c_reg(pd->regs, DT_ID, &tmp);
1298 if (tmp != DT3155_ID)
1299 return -ENODEV;
1300
1301 /* initialize AD LUT */
1302 write_i2c_reg(pd->regs, AD_ADDR, 0);
1303 for (i = 0; i < 256; i++)
1304 write_i2c_reg(pd->regs, AD_LUT, i);
1305
1306 /* initialize ADC references */
1307 /* FIXME: pos_ref & neg_ref depend on VT_50HZ */
1308 write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG);
1309 write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3);
1310 write_i2c_reg(pd->regs, AD_ADDR, AD_POS_REF);
1311 write_i2c_reg(pd->regs, AD_CMD, 34);
1312 write_i2c_reg(pd->regs, AD_ADDR, AD_NEG_REF);
1313 write_i2c_reg(pd->regs, AD_CMD, 0);
1314
1315 /* initialize PM LUT */
1316 write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM);
1317 for (i = 0; i < 256; i++) {
1318 write_i2c_reg(pd->regs, PM_LUT_ADDR, i);
1319 write_i2c_reg(pd->regs, PM_LUT_DATA, i);
1320 }
1321 write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM | PM_LUT_SEL);
1322 for (i = 0; i < 256; i++) {
1323 write_i2c_reg(pd->regs, PM_LUT_ADDR, i);
1324 write_i2c_reg(pd->regs, PM_LUT_DATA, i);
1325 }
1326 write_i2c_reg(pd->regs, CONFIG, pd->config); /* ACQ_MODE_EVEN */
1327
1328 /* select chanel 1 for input and set sync level */
1329 write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG);
1330 write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3);
1331
1332 /* allocate and pci_map memory, and initialize the DMA machine */
1333 buf = dt3155_get_buf(dt3155_free_bufs);
1334 if (!buf) {
1335 printk(KERN_ERR "dt3155: dt3155_get_buf "
1336 "(in dt3155_init_board) failed\n");
1337 return -ENOMEM;
1338 }
1339 buf->dma = pci_map_single(dev, buf->cpu,
1340 DT3155_BUF_SIZE, PCI_DMA_FROMDEVICE);
1341 if (pci_dma_mapping_error(dev, buf->dma)) {
1342 printk(KERN_ERR "dt3155: pci_map_single failed\n");
1343 dt3155_put_buf(buf, dt3155_free_bufs);
1344 return -ENOMEM;
1345 }
1346 iowrite32(buf->dma, pd->regs + EVEN_DMA_START);
1347 iowrite32(buf->dma, pd->regs + ODD_DMA_START);
1348 iowrite32(0, pd->regs + EVEN_DMA_STRIDE);
1349 iowrite32(0, pd->regs + ODD_DMA_STRIDE);
1350
1351 /* Perform a pseudo even field acquire */
1352 iowrite32(FIFO_EN | SRST | CAP_CONT_ODD, pd->regs + CSR1);
1353 write_i2c_reg(pd->regs, CSR2, pd->csr2 | SYNC_SNTL);
1354 write_i2c_reg(pd->regs, CONFIG, pd->config);
1355 write_i2c_reg(pd->regs, EVEN_CSR, CSR_SNGL);
1356 write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | SYNC_SNTL);
1357 msleep(100);
1358 read_i2c_reg(pd->regs, CSR2, &tmp);
1359 write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_SNGL | CSR_DONE);
1360 write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_SNGL | CSR_DONE);
1361 write_i2c_reg(pd->regs, CSR2, pd->csr2);
1362 iowrite32(FIFO_EN | SRST | FLD_DN_EVEN | FLD_DN_ODD, pd->regs + CSR1);
1363
1364 /* pci_unmap and deallocate memory */
1365 pci_unmap_single(dev, buf->dma, DT3155_BUF_SIZE, PCI_DMA_FROMDEVICE);
1366 dt3155_put_buf(buf, dt3155_free_bufs);
1367 if (tmp & BUSY_EVEN) {
1368 printk(KERN_ERR "dt3155: BUSY_EVEN not cleared\n");
1369 return -EIO;
1370 }
1371 return 0;
1372}
1373
1374static struct video_device dt3155_vdev = {
1375 .name = DT3155_NAME,
1376 .fops = &dt3155_fops,
1377 .ioctl_ops = &dt3155_ioctl_ops,
1378 .minor = -1,
1379 .release = video_device_release,
1380 .tvnorms = V4L2_STD_ALL,
1381 .current_norm = DT3155_CURRENT_NORM,
1382};
1383
1384static int __devinit
1385dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id)
1386{
1387 int err = -ENODEV;
1388 struct dt3155_priv *pd;
1389
1390 printk(KERN_INFO "dt3155: probe()\n");
1391 if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
1392 printk(KERN_ERR "dt3155: cannot set dma_mask\n");
1393 return -ENODEV;
1394 }
1395 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
1396 if (!pd) {
1397 printk(KERN_ERR "dt3155: cannot allocate dt3155_priv\n");
1398 return -ENOMEM;
1399 }
1400 pd->vdev = video_device_alloc();
1401 if (!pd->vdev) {
1402 printk(KERN_ERR "dt3155: cannot allocate vdp structure\n");
1403 goto err_video_device_alloc;
1404 }
1405 *pd->vdev = dt3155_vdev;
1406 pci_set_drvdata(dev, pd); /* for use in dt3155_remove() */
1407 video_set_drvdata(pd->vdev, pd); /* for use in video_fops */
1408 pd->users = 0;
1409 pd->acq_fp = NULL;
1410 pd->pdev = dev;
1411 INIT_LIST_HEAD(&pd->dmaq);
1412 init_waitqueue_head(&pd->do_dma);
1413 mutex_init(&pd->mux);
1414 pd->csr2 = csr2_init;
1415 pd->config = config_init;
1416 err = pci_enable_device(pd->pdev);
1417 if (err) {
1418 printk(KERN_ERR "dt3155: pci_dev not enabled\n");
1419 goto err_enable_dev;
1420 }
1421 err = pci_request_region(pd->pdev, 0, pci_name(pd->pdev));
1422 if (err)
1423 goto err_req_region;
1424 pd->regs = pci_iomap(pd->pdev, 0, pci_resource_len(pd->pdev, 0));
1425 if (!pd->regs) {
1426 err = -ENOMEM;
1427 printk(KERN_ERR "dt3155: pci_iomap failed\n");
1428 goto err_pci_iomap;
1429 }
1430 err = dt3155_init_board(pd->pdev);
1431 if (err) {
1432 printk(KERN_ERR "dt3155: dt3155_init_board failed\n");
1433 goto err_init_board;
1434 }
1435 err = video_register_device(pd->vdev, VFL_TYPE_GRABBER, -1);
1436 if (err) {
1437 printk(KERN_ERR "dt3155: Cannot register video device\n");
1438 goto err_init_board;
1439 }
1440 printk(KERN_INFO "dt3155: /dev/video%i is ready\n", pd->vdev->minor);
1441 return 0; /* success */
1442
1443err_init_board:
1444 pci_iounmap(pd->pdev, pd->regs);
1445err_pci_iomap:
1446 pci_release_region(pd->pdev, 0);
1447err_req_region:
1448 pci_disable_device(pd->pdev);
1449err_enable_dev:
1450 video_device_release(pd->vdev);
1451err_video_device_alloc:
1452 kfree(pd);
1453 return err;
1454}
1455
1456static void __devexit
1457dt3155_remove(struct pci_dev *dev)
1458{
1459 struct dt3155_priv *pd = pci_get_drvdata(dev);
1460
1461 printk(KERN_INFO "dt3155: remove()\n");
1462 video_unregister_device(pd->vdev);
1463 pci_iounmap(dev, pd->regs);
1464 pci_release_region(pd->pdev, 0);
1465 pci_disable_device(pd->pdev);
1466 /*
1467 * video_device_release() is invoked automatically
1468 * see: struct video_device dt3155_vdev
1469 */
1470 kfree(pd);
1471}
1472
1473static DEFINE_PCI_DEVICE_TABLE(pci_ids) = {
1474 { PCI_DEVICE(DT3155_VENDOR_ID, DT3155_DEVICE_ID) },
1475 { 0, /* zero marks the end */ },
1476};
1477MODULE_DEVICE_TABLE(pci, pci_ids);
1478
1479static struct pci_driver pci_driver = {
1480 .name = DT3155_NAME,
1481 .id_table = pci_ids,
1482 .probe = dt3155_probe,
1483 .remove = __devexit_p(dt3155_remove),
1484};
1485
1486static int __init
1487dt3155_init_module(void)
1488{
1489 int err;
1490
1491 printk(KERN_INFO "dt3155: ==================\n");
1492 printk(KERN_INFO "dt3155: init()\n");
1493 dt3155_chunks = dt3155_init_chunks_fifo();
1494 if (!dt3155_chunks) {
1495 err = -ENOMEM;
1496 printk(KERN_ERR "dt3155: cannot init dt3155_chunks_fifo\n");
1497 goto err_init_chunks_fifo;
1498 }
1499 dt3155_free_bufs = dt3155_init_ibufs_fifo(dt3155_chunks,
1500 DT3155_BUF_SIZE);
1501 if (!dt3155_free_bufs) {
1502 err = -ENOMEM;
1503 printk(KERN_ERR "dt3155: cannot dt3155_init_ibufs_fifo\n");
1504 goto err_init_ibufs_fifo;
1505 }
1506 dt3155_alloc_bufs = dt3155_init_fifo();
1507 if (!dt3155_alloc_bufs) {
1508 err = -ENOMEM;
1509 printk(KERN_ERR "dt3155: cannot dt3155_init_fifo\n");
1510 goto err_init_fifo;
1511 }
1512 err = pci_register_driver(&pci_driver);
1513 if (err) {
1514 printk(KERN_ERR "dt3155: cannot register pci_driver\n");
1515 goto err_register_driver;
1516 }
1517 return 0; /* succes */
1518err_register_driver:
1519 dt3155_free_fifo(dt3155_alloc_bufs);
1520err_init_fifo:
1521 dt3155_free_ibufs_fifo(dt3155_free_bufs);
1522err_init_ibufs_fifo:
1523 dt3155_free_chunks_fifo(dt3155_chunks);
1524err_init_chunks_fifo:
1525 return err;
1526}
1527
1528static void __exit
1529dt3155_exit_module(void)
1530{
1531 pci_unregister_driver(&pci_driver);
1532 dt3155_free_fifo(dt3155_alloc_bufs);
1533 dt3155_free_ibufs_fifo(dt3155_free_bufs);
1534 dt3155_free_chunks_fifo(dt3155_chunks);
1535 printk(KERN_INFO "dt3155: exit()\n");
1536 printk(KERN_INFO "dt3155: ==================\n");
1537}
1538
1539module_init(dt3155_init_module);
1540module_exit(dt3155_exit_module);
1541
1542MODULE_DESCRIPTION("video4linux pci-driver for dt3155 frame grabber");
1543MODULE_AUTHOR("Marin Mitov <mitov@issp.bas.bg>");
1544MODULE_VERSION(DT3155_VERSION);
1545MODULE_LICENSE("GPL");
This page took 0.08723 seconds and 5 git commands to generate.