3 Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
4 Jason Lapenta, Scott Smedley, Greg Sharp
6 This file is part of the DT3155 Device Driver.
8 The DT3155 Device Driver is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
13 The DT3155 Device Driver is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with the DT3155 Device Driver; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 Date Programmer Description of changes made
26 -------------------------------------------------------------------
28 10-Oct-2001 SS port to 2.4 kernel
29 02-Apr-2002 SS Mods to use allocator as a standalone module;
30 Merged John Roll's changes (john@cfa.harvard.edu)
31 to make work with multiple boards.
32 02-Jul-2002 SS Merged James Rose's chages (rosejr@purdue.edu) to:
33 * fix successive interrupt-driven captures
34 * add select/poll support.
35 10-Jul-2002 GCS Add error check when ndevices > MAXBOARDS.
36 02-Aug-2002 GCS Fix field mode so that odd (lower) field is stored
37 in lower half of buffer.
38 05-Aug-2005 SS port to 2.6 kernel.
39 26-Oct-2009 SS port to 2.6.30 kernel.
43 ** appended "mem=124" in lilo.conf to allow for 4megs free on my 128meg system.
44 * using allocator.c and allocator.h from o'reilly book (alessandro rubini)
45 ftp://ftp.systemy.it/pub/develop (see README.allocator)
47 + might want to get rid of MAXboards for allocating initial buffer.
48 confusing and not necessary
50 + in dt3155_exit the MOD_IN_USE looks like it is check after it should
52 * GFP_DMA should not be set with a PCI system (pg 291)
54 - NJC why are only two buffers allowed? (see isr, approx line 358)
58 #include <linux/module.h>
59 #include <linux/interrupt.h>
60 #include <linux/mutex.h>
61 #include <linux/pci.h>
62 #include <linux/types.h>
63 #include <linux/poll.h>
64 #include <linux/sched.h>
65 #include <linux/smp_lock.h>
68 #include <linux/uaccess.h>
71 #include "dt3155_drv.h"
72 #include "dt3155_isr.h"
73 #include "dt3155_io.h"
74 #include "allocator.h"
77 MODULE_LICENSE("GPL");
79 /* Error variable. Zero means no error. */
80 static DEFINE_MUTEX(dt3155_mutex
);
83 #ifndef PCI_DEVICE_ID_INTEL_7116
84 #define PCI_DEVICE_ID_INTEL_7116 0x1223
87 #define DT3155_VENDORID PCI_VENDOR_ID_INTEL
88 #define DT3155_DEVICEID PCI_DEVICE_ID_INTEL_7116
92 #define DT_3155_DEBUG_MSG(x,y) printk(x,y)
94 #define DT_3155_DEBUG_MSG(x,y)
97 /* wait queue for interrupts */
98 wait_queue_head_t dt3155_read_wait_queue
[MAXBOARDS
];
100 /* set to dynamicaly allocate, but it is tunable: */
101 /* insmod DT_3155 dt3155 dt3155_major=XX */
102 int dt3155_major
= 0;
104 /* The minor numbers are 0 and 1 ... they are not tunable.
105 * They are used as the indices for the structure vectors,
106 * and register address vectors
109 /* Global structures and variables */
111 /* Status of each device */
112 struct dt3155_status dt3155_status
[MAXBOARDS
];
114 /* kernel logical address of the board */
115 static void __iomem
*dt3155_lbase
[MAXBOARDS
] = { NULL
121 u32 dt3155_dev_open
[MAXBOARDS
] = {0
132 * Stops interrupt generation right away and resets the status
133 * to idle. I don't know why this works and the other way doesn't.
136 static void quick_stop (int minor
)
138 struct dt3155_status
*dts
= &dt3155_status
[minor
];
139 struct dt3155_fbuffer
*fb
= &dts
->fbuffer
;
141 // TODO: scott was here
145 int_csr_r
.reg
= readl(dt3155_lbase
[minor
] + INT_CSR
);
146 /* disable interrupts */
147 int_csr_r
.fld
.FLD_END_EVE_EN
= 0;
148 int_csr_r
.fld
.FLD_END_ODD_EN
= 0;
149 writel(int_csr_r
.reg
, dt3155_lbase
[minor
] + INT_CSR
);
151 dts
->state
&= ~(DT3155_STATE_STOP
|0xff);
152 /* mark the system stopped: */
153 dts
->state
|= DT3155_STATE_IDLE
;
154 fb
->stop_acquire
= 0;
155 fb
->even_stopped
= 0;
157 dts
->state
|= DT3155_STATE_STOP
;
158 fb
->stop_acquire
= 1;
164 /*****************************************************
165 * dt3155_isr() Interrupt service routien
167 * - looks like this isr supports IRQ sharing (or could) JML
168 * - Assumes irq's are disabled, via SA_INTERRUPT flag
169 * being set in request_irq() call from dt3155_init()
170 *****************************************************/
171 static void dt3155_isr(int irq
, void *dev_id
, struct pt_regs
*regs
)
178 struct dt3155_status
*dts
;
179 struct dt3155_fbuffer
*fb
;
182 I2C_EVEN_CSR i2c_even_csr
;
183 I2C_ODD_CSR i2c_odd_csr
;
185 /* find out who issued the interrupt */
186 for (index
= 0; index
< ndevices
; index
++) {
187 if(dev_id
== (void*) &dt3155_status
[index
])
194 /* hopefully we should not get here */
195 if (minor
< 0 || minor
>= MAXBOARDS
) {
196 printk(KERN_ERR
"dt3155_isr called with invalid dev_id\n");
200 mmio
= dt3155_lbase
[minor
];
201 dts
= &dt3155_status
[minor
];
204 /* Check for corruption and set a flag if so */
205 csr1_r
.reg
= readl(mmio
+ CSR1
);
207 if ((csr1_r
.fld
.FLD_CRPT_EVE
) || (csr1_r
.fld
.FLD_CRPT_ODD
))
209 /* TODO: this should probably stop acquisition */
210 /* and set some flags so that dt3155_read */
211 /* returns an error next time it is called */
212 dt3155_errno
= DT_ERR_CORRUPT
;
213 printk(KERN_ERR
"dt3155: corrupt field\n");
217 int_csr_r
.reg
= readl(mmio
+ INT_CSR
);
219 /* Handle the even field ... */
220 if (int_csr_r
.fld
.FLD_END_EVE
)
222 if ((dts
->state
& DT3155_STATE_MODE
) == DT3155_STATE_FLD
)
227 ReadI2C(mmio
, EVEN_CSR
, &i2c_even_csr
.reg
);
229 /* Clear the interrupt? */
230 int_csr_r
.fld
.FLD_END_EVE
= 1;
232 /* disable the interrupt if last field */
233 if (fb
->stop_acquire
)
235 printk(KERN_INFO
"dt3155: even stopped.\n");
236 fb
->even_stopped
= 1;
237 if (i2c_even_csr
.fld
.SNGL_EVE
)
239 int_csr_r
.fld
.FLD_END_EVE_EN
= 0;
243 i2c_even_csr
.fld
.SNGL_EVE
= 1;
247 writel(int_csr_r
.reg
, mmio
+ INT_CSR
);
249 /* Set up next DMA if we are doing FIELDS */
250 if ((dts
->state
& DT3155_STATE_MODE
) == DT3155_STATE_FLD
)
252 /* GCS (Aug 2, 2002) -- In field mode, dma the odd field
253 into the lower half of the buffer */
254 const u32 stride
= dts
->config
.cols
;
255 buffer_addr
= fb
->frame_info
[fb
->active_buf
].addr
+
256 (DT3155_MAX_ROWS
/ 2) * stride
;
257 local_save_flags(flags
);
259 wake_up_interruptible(&dt3155_read_wait_queue
[minor
]);
261 /* Set up the DMA address for the next field */
262 local_irq_restore(flags
);
263 writel(buffer_addr
, mmio
+ ODD_DMA_START
);
266 /* Check for errors. */
267 i2c_even_csr
.fld
.DONE_EVE
= 1;
268 if (i2c_even_csr
.fld
.ERROR_EVE
)
269 dt3155_errno
= DT_ERR_OVERRUN
;
271 WriteI2C(mmio
, EVEN_CSR
, i2c_even_csr
.reg
);
273 /* Note that we actually saw an even field meaning */
274 /* that subsequent odd field complete the frame */
275 fb
->even_happened
= 1;
277 /* recording the time that the even field finished, this should be */
278 /* about time in the middle of the frame */
279 do_gettimeofday(&fb
->frame_info
[fb
->active_buf
].time
);
283 /* ... now handle the odd field */
284 if (int_csr_r
.fld
.FLD_END_ODD
)
286 ReadI2C(mmio
, ODD_CSR
, &i2c_odd_csr
.reg
);
288 /* Clear the interrupt? */
289 int_csr_r
.fld
.FLD_END_ODD
= 1;
291 if (fb
->even_happened
||
292 (dts
->state
& DT3155_STATE_MODE
) == DT3155_STATE_FLD
)
297 if (fb
->stop_acquire
&& fb
->even_stopped
)
299 printk(KERN_DEBUG
"dt3155: stopping odd..\n");
300 if (i2c_odd_csr
.fld
.SNGL_ODD
)
302 /* disable interrupts */
303 int_csr_r
.fld
.FLD_END_ODD_EN
= 0;
304 dts
->state
&= ~(DT3155_STATE_STOP
|0xff);
306 /* mark the system stopped: */
307 dts
->state
|= DT3155_STATE_IDLE
;
308 fb
->stop_acquire
= 0;
309 fb
->even_stopped
= 0;
311 printk(KERN_DEBUG
"dt3155: state is now %x\n", dts
->state
);
315 i2c_odd_csr
.fld
.SNGL_ODD
= 1;
319 writel(int_csr_r
.reg
, mmio
+ INT_CSR
);
321 /* if the odd field has been acquired, then */
322 /* change the next dma location for both fields */
323 /* and wake up the process if sleeping */
324 if (fb
->even_happened
||
325 (dts
->state
& DT3155_STATE_MODE
) == DT3155_STATE_FLD
)
328 local_save_flags(flags
);
334 if (fb
->nbuffers
> 2)
336 if (!are_empty_buffers(fb
))
338 /* The number of active + locked buffers is
339 * at most 2, and since there are none empty, there
340 * must be at least nbuffers-2 ready buffers.
341 * This is where we 'drop frames', oldest first. */
342 push_empty(fb
, pop_ready(fb
));
345 /* The ready_que can't be full, since we know
346 * there is one active buffer right now, so it's safe
347 * to push the active buf on the ready_que. */
348 push_ready(fb
, fb
->active_buf
);
349 /* There's at least 1 empty -- make it active */
350 fb
->active_buf
= pop_empty(fb
);
351 fb
->frame_info
[fb
->active_buf
].tag
= ++unique_tag
;
353 else /* nbuffers == 2, special case */
354 { /* There is 1 active buffer.
355 * If there is a locked buffer, keep the active buffer
356 * the same -- that means we drop a frame.
358 if (fb
->locked_buf
< 0)
360 push_ready(fb
, fb
->active_buf
);
361 if (are_empty_buffers(fb
))
363 fb
->active_buf
= pop_empty(fb
);
366 { /* no empty or locked buffers, so use a readybuf */
367 fb
->active_buf
= pop_ready(fb
);
376 fb
->even_happened
= 0;
378 wake_up_interruptible(&dt3155_read_wait_queue
[minor
]);
380 local_irq_restore(flags
);
384 /* Set up the DMA address for the next frame/field */
385 buffer_addr
= fb
->frame_info
[fb
->active_buf
].addr
;
386 if ((dts
->state
& DT3155_STATE_MODE
) == DT3155_STATE_FLD
)
388 writel(buffer_addr
, mmio
+ EVEN_DMA_START
);
392 writel(buffer_addr
, mmio
+ EVEN_DMA_START
);
394 writel(buffer_addr
+ dts
->config
.cols
, mmio
+ ODD_DMA_START
);
397 /* Do error checking */
398 i2c_odd_csr
.fld
.DONE_ODD
= 1;
399 if (i2c_odd_csr
.fld
.ERROR_ODD
)
400 dt3155_errno
= DT_ERR_OVERRUN
;
402 WriteI2C(mmio
, ODD_CSR
, i2c_odd_csr
.reg
);
406 /* If we get here, the Odd Field wasn't it either... */
407 printk(KERN_DEBUG
"neither even nor odd. shared perhaps?\n");
410 /*****************************************************
411 * init_isr(int minor)
412 * turns on interupt generation for the card
413 * designated by "minor".
414 * It is called *only* from inside ioctl().
415 *****************************************************/
416 static void dt3155_init_isr(int minor
)
418 struct dt3155_status
*dts
= &dt3155_status
[minor
];
419 struct dt3155_fbuffer
*fb
= &dts
->fbuffer
;
420 void __iomem
*mmio
= dt3155_lbase
[minor
];
421 u32 dma_addr
= fb
->frame_info
[fb
->active_buf
].addr
;
422 const u32 stride
= dts
->config
.cols
;
427 switch (dts
->state
& DT3155_STATE_MODE
)
429 case DT3155_STATE_FLD
:
431 writel(dma_addr
, mmio
+ EVEN_DMA_START
);
432 writel(0, mmio
+ EVEN_DMA_STRIDE
);
433 writel(0, mmio
+ ODD_DMA_STRIDE
);
437 case DT3155_STATE_FRAME
:
440 writel(dma_addr
, mmio
+ EVEN_DMA_START
);
441 writel(dma_addr
+ stride
, mmio
+ ODD_DMA_START
);
442 writel(stride
, mmio
+ EVEN_DMA_STRIDE
);
443 writel(stride
, mmio
+ ODD_DMA_STRIDE
);
448 /* 50/60 Hz should be set before this point but let's make sure it is */
451 ReadI2C(mmio
, CSR2
, &i2c_csr2
.reg
);
452 i2c_csr2
.fld
.HZ50
= FORMAT50HZ
;
453 WriteI2C(mmio
, CSR2
, i2c_csr2
.reg
);
455 /* enable busmaster chip, clear flags */
459 * shouldn't we be concered with continuous values of
460 * DT3155_SNAP & DT3155_ACQ here? (SS)
464 csr1_r
.fld
.CAP_CONT_EVE
= 1; /* use continuous capture bits to */
465 csr1_r
.fld
.CAP_CONT_ODD
= 1; /* enable */
466 csr1_r
.fld
.FLD_DN_EVE
= 1; /* writing a 1 clears flags */
467 csr1_r
.fld
.FLD_DN_ODD
= 1;
468 csr1_r
.fld
.SRST
= 1; /* reset - must be 1 */
469 csr1_r
.fld
.FIFO_EN
= 1; /* fifo control - must be 1 */
470 csr1_r
.fld
.FLD_CRPT_EVE
= 1; /* writing a 1 clears flags */
471 csr1_r
.fld
.FLD_CRPT_ODD
= 1;
473 writel(csr1_r
.reg
, mmio
+ CSR1
);
475 /* Enable interrupts at the end of each field */
478 int_csr_r
.fld
.FLD_END_EVE_EN
= 1;
479 int_csr_r
.fld
.FLD_END_ODD_EN
= 1;
480 int_csr_r
.fld
.FLD_START_EN
= 0;
482 writel(int_csr_r
.reg
, mmio
+ INT_CSR
);
484 /* start internal BUSY bits */
486 ReadI2C(mmio
, CSR2
, &i2c_csr2
.reg
);
487 i2c_csr2
.fld
.BUSY_ODD
= 1;
488 i2c_csr2
.fld
.BUSY_EVE
= 1;
489 WriteI2C(mmio
, CSR2
, i2c_csr2
.reg
);
491 /* Now its up to the interrupt routine!! */
497 /*****************************************************
500 *****************************************************/
501 static int dt3155_ioctl(struct inode
*inode
,
506 int minor
= MINOR(inode
->i_rdev
); /* What device are we ioctl()'ing? */
507 void __user
*up
= (void __user
*)arg
;
508 struct dt3155_status
*dts
= &dt3155_status
[minor
];
509 struct dt3155_fbuffer
*fb
= &dts
->fbuffer
;
511 if (minor
>= MAXBOARDS
|| minor
< 0)
514 /* make sure it is valid command */
515 if (_IOC_NR(cmd
) > DT3155_IOC_MAXNR
)
517 printk(KERN_INFO
"DT3155: invalid IOCTL(0x%x)\n", cmd
);
518 printk(KERN_INFO
"DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
519 (unsigned int)DT3155_GET_CONFIG
,
520 (unsigned int)DT3155_SET_CONFIG
,
521 (unsigned int)DT3155_START
,
522 (unsigned int)DT3155_STOP
,
523 (unsigned int)DT3155_FLUSH
);
529 case DT3155_SET_CONFIG
:
531 if (dts
->state
!= DT3155_STATE_IDLE
)
535 struct dt3155_config tmp
;
536 if (copy_from_user(&tmp
, up
, sizeof(tmp
)))
538 /* check for valid settings */
539 if (tmp
.rows
> DT3155_MAX_ROWS
||
540 tmp
.cols
> DT3155_MAX_COLS
||
541 (tmp
.acq_mode
!= DT3155_MODE_FRAME
&&
542 tmp
.acq_mode
!= DT3155_MODE_FIELD
) ||
543 (tmp
.continuous
!= DT3155_SNAP
&&
544 tmp
.continuous
!= DT3155_ACQ
))
552 case DT3155_GET_CONFIG
:
554 if (copy_to_user(up
, dts
, sizeof(*dts
)))
558 case DT3155_FLUSH
: /* Flushes the buffers -- ensures fresh data */
560 if (dts
->state
!= DT3155_STATE_IDLE
)
562 return dt3155_flush(fb
);
566 if (dts
->state
& DT3155_STATE_STOP
|| fb
->stop_acquire
)
569 if (dts
->state
== DT3155_STATE_IDLE
)
573 if (copy_to_user(up
, dts
, sizeof(*dts
)))
579 if (dts
->state
!= DT3155_STATE_IDLE
)
582 fb
->stop_acquire
= 0;
585 /* Set the MODE in the status -- we default to FRAME */
586 if (dts
->config
.acq_mode
== DT3155_MODE_FIELD
)
588 dts
->state
= DT3155_STATE_FLD
;
592 dts
->state
= DT3155_STATE_FRAME
;
595 dt3155_init_isr(minor
);
596 if (copy_to_user(up
, dts
, sizeof(*dts
)))
602 printk(KERN_INFO
"DT3155: invalid IOCTL(0x%x)\n", cmd
);
603 printk(KERN_INFO
"DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
604 (unsigned int)DT3155_GET_CONFIG
,
605 (unsigned int)DT3155_SET_CONFIG
,
606 DT3155_START
, DT3155_STOP
, DT3155_FLUSH
);
613 /*****************************************************
616 * only allow the user to mmap the registers and buffer
617 * It is quite possible that this is broken, since the
618 * addition of of the capacity for two cards!!!!!!!!
619 * It *looks* like it should work but since I'm not
620 * sure how to use it, I'm not actually sure. (NJC? ditto by SS)
621 *****************************************************/
622 static int dt3155_mmap (struct file
* file
, struct vm_area_struct
* vma
)
624 /* which device are we mmapping? */
625 int minor
= MINOR(file
->f_dentry
->d_inode
->i_rdev
);
626 struct dt3155_status
*dts
= &dt3155_status
[minor
];
627 unsigned long offset
;
628 offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
630 if (offset
>= __pa(high_memory
) || (file
->f_flags
& O_SYNC
))
631 vma
->vm_flags
|= VM_IO
;
633 /* Don't try to swap out physical pages.. */
634 vma
->vm_flags
|= VM_RESERVED
;
636 /* they are mapping the registers or the buffer */
637 if ((offset
== dts
->reg_addr
&&
638 vma
->vm_end
- vma
->vm_start
== PCI_PAGE_SIZE
) ||
639 (offset
== dts
->mem_addr
&&
640 vma
->vm_end
- vma
->vm_start
== dts
->mem_size
))
642 if (remap_pfn_range(vma
,
644 offset
>> PAGE_SHIFT
,
645 vma
->vm_end
- vma
->vm_start
,
646 vma
->vm_page_prot
)) {
647 printk(KERN_INFO
"DT3155: remap_page_range() failed.\n");
653 printk(KERN_INFO
"DT3155: dt3155_mmap() bad call.\n");
661 /*****************************************************
664 * Our special open code.
665 * MOD_INC_USE_COUNT make sure that the driver memory is not freed
666 * while the device is in use.
667 *****************************************************/
668 static int dt3155_open(struct inode
* inode
, struct file
* filep
)
670 int minor
= MINOR(inode
->i_rdev
); /* what device are we opening? */
671 struct dt3155_status
*dts
= &dt3155_status
[minor
];
672 struct dt3155_fbuffer
*fb
= &dts
->fbuffer
;
674 if (dt3155_dev_open
[minor
]) {
675 printk(KERN_INFO
"DT3155: Already opened by another process.\n");
679 if (dts
->device_installed
==0)
681 printk(KERN_INFO
"DT3155 Open Error: No such device dt3155 minor number %d\n",
686 if (dts
->state
!= DT3155_STATE_IDLE
) {
687 printk(KERN_INFO
"DT3155: Not in idle state (state = %x)\n",
692 printk(KERN_INFO
"DT3155: Device opened.\n");
694 dt3155_dev_open
[minor
] = 1 ;
698 /* Disable ALL interrupts */
699 writel(0, dt3155_lbase
[minor
] + INT_CSR
);
701 init_waitqueue_head(&(dt3155_read_wait_queue
[minor
]));
707 /*****************************************************
710 * Now decrement the use count.
712 *****************************************************/
713 static int dt3155_close(struct inode
*inode
, struct file
*filep
)
715 int minor
= MINOR(inode
->i_rdev
); /* which device are we closing */
716 struct dt3155_status
*dts
= &dt3155_status
[minor
];
718 if (!dt3155_dev_open
[minor
])
720 printk(KERN_INFO
"DT3155: attempt to CLOSE a not OPEN device\n");
724 dt3155_dev_open
[minor
] = 0;
726 if (dts
->state
!= DT3155_STATE_IDLE
)
734 /*****************************************************
737 *****************************************************/
738 static ssize_t
dt3155_read(struct file
*filep
, char __user
*buf
,
739 size_t count
, loff_t
*ppos
)
741 /* which device are we reading from? */
742 int minor
= MINOR(filep
->f_dentry
->d_inode
->i_rdev
);
745 struct dt3155_status
*dts
= &dt3155_status
[minor
];
746 struct dt3155_fbuffer
*fb
= &dts
->fbuffer
;
747 struct frame_info
*frame_info
;
749 /* TODO: this should check the error flag and */
750 /* return an error on hardware failures */
751 if (count
!= sizeof(struct dt3155_read
))
753 printk(KERN_INFO
"DT3155 ERROR (NJC): count is not right\n");
758 /* Hack here -- I'm going to allow reading even when idle.
759 * this is so that the frames can be read after STOP has
760 * been called. Leaving it here, commented out, as a reminder
761 * for a short while to make sure there are no problems.
762 * Note that if the driver is not opened in non_blocking mode,
763 * and the device is idle, then it could sit here forever! */
765 /* if (dts->state == DT3155_STATE_IDLE)*/
768 /* non-blocking reads should return if no data */
769 if (filep
->f_flags
& O_NDELAY
)
771 if ((frame_index
= dt3155_get_ready_buffer(fb
)) < 0) {
772 /* printk("dt3155: no buffers available (?)\n"); */
780 * sleep till data arrives , or we get interrupted.
781 * Note that wait_event_interruptible() does not actually
782 * sleep/wait if it's condition evaluates to true upon entry.
784 frame_index
= dt3155_get_ready_buffer(fb
);
785 wait_event_interruptible(dt3155_read_wait_queue
[minor
], frame_index
>= 0);
789 printk(KERN_INFO
"DT3155: read: interrupted\n");
796 frame_info
= &fb
->frame_info
[frame_index
];
798 /* make this an offset */
799 offset
= frame_info
->addr
- dts
->mem_addr
;
801 put_user(offset
, (unsigned int __user
*)buf
);
803 put_user(fb
->frame_count
, (unsigned int __user
*)buf
);
805 put_user(dts
->state
, (unsigned int __user
*)buf
);
807 if (copy_to_user(buf
, frame_info
, sizeof(*frame_info
)))
810 return sizeof(struct dt3155_read
);
813 static unsigned int dt3155_poll (struct file
* filp
, poll_table
*wait
)
815 int minor
= MINOR(filp
->f_dentry
->d_inode
->i_rdev
);
816 struct dt3155_status
*dts
= &dt3155_status
[minor
];
817 struct dt3155_fbuffer
*fb
= &dts
->fbuffer
;
819 if (!is_ready_buf_empty(fb
))
820 return POLLIN
| POLLRDNORM
;
822 poll_wait (filp
, &dt3155_read_wait_queue
[minor
], wait
);
828 dt3155_unlocked_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
832 mutex_lock(&dt3155_mutex
);
833 ret
= dt3155_ioctl(file
->f_path
.dentry
->d_inode
, file
, cmd
, arg
);
834 mutex_unlock(&dt3155_mutex
);
839 /*****************************************************
840 * file operations supported by DT3155 driver
841 * needed by dt3155_init
843 *****************************************************/
844 static struct file_operations dt3155_fops
= {
846 .unlocked_ioctl
= dt3155_unlocked_ioctl
,
850 .release
= dt3155_close
854 /*****************************************************
857 * PCI has been totally reworked in 2.1..
858 *****************************************************/
859 static int find_PCI (void)
861 struct pci_dev
*pci_dev
= NULL
;
862 struct dt3155_status
*dts
;
863 int error
, pci_index
= 0;
864 unsigned short rev_device
;
868 while ((pci_dev
= pci_get_device
869 (DT3155_VENDORID
, DT3155_DEVICEID
, pci_dev
)) != NULL
)
871 dts
= &dt3155_status
[pci_index
++];
873 /* Is it really there? */
875 pci_read_config_word(pci_dev
, PCI_CLASS_DEVICE
, &rev_device
)))
879 DT_3155_DEBUG_MSG("DT3155: Device number %d \n", pci_index
);
881 /* Make sure the driver was compiled with enough buffers to handle
883 if (pci_index
> MAXBOARDS
) {
884 printk(KERN_ERR
"DT3155: Found %d devices, but driver only configured "
886 "DT3155: Please change MAXBOARDS in dt3155.h\n",
887 pci_index
, MAXBOARDS
);
891 /* Now, just go out and make sure that this/these device(s) is/are
892 actually mapped into the kernel address space */
893 if ((error
= pci_read_config_dword(pci_dev
, PCI_BASE_ADDRESS_0
,
896 printk(KERN_INFO
"DT3155: Was not able to find device\n");
900 DT_3155_DEBUG_MSG("DT3155: Base address 0 for device is %lx \n", base
);
901 dts
->reg_addr
= base
;
903 /* Remap the base address to a logical address through which we
905 dt3155_lbase
[pci_index
- 1] = ioremap(base
, PCI_PAGE_SIZE
);
906 dts
->reg_addr
= base
;
907 DT_3155_DEBUG_MSG("DT3155: New logical address is %p \n",
908 dt3155_lbase
[pci_index
-1]);
909 if (!dt3155_lbase
[pci_index
-1])
911 printk(KERN_INFO
"DT3155: Unable to remap control registers\n");
915 if ((error
= pci_read_config_byte(pci_dev
, PCI_INTERRUPT_LINE
, &irq
)))
917 printk(KERN_INFO
"DT3155: Was not able to find device\n");
921 DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq
);
923 /* Set flag: kth device found! */
924 dts
->device_installed
= 1;
925 printk(KERN_INFO
"DT3155: Installing device %d w/irq %d and address %p\n",
928 dt3155_lbase
[pci_index
-1]);
931 ndevices
= pci_index
;
936 pci_dev_put(pci_dev
);
940 u32 allocatorAddr
= 0;
943 static int __init
dt3155_init(void)
945 struct dt3155_status
*dts
;
948 char *devname
[MAXBOARDS
];
950 devname
[0] = "dt3155a";
952 devname
[1] = "dt3155b";
955 printk(KERN_INFO
"DT3155: Loading module...\n");
957 /* Register the device driver */
958 rcode
= register_chrdev(dt3155_major
, "dt3155", &dt3155_fops
);
961 printk(KERN_INFO
"DT3155: register_chrdev failed \n");
965 if(dt3155_major
== 0)
966 dt3155_major
= rcode
; /* dynamic */
969 /* init the status variables. */
970 /* DMA memory is taken care of in setup_buffers() */
971 for (index
= 0; index
< MAXBOARDS
; index
++)
973 dts
= &dt3155_status
[index
];
975 dts
->config
.acq_mode
= DT3155_MODE_FRAME
;
976 dts
->config
.continuous
= DT3155_ACQ
;
977 dts
->config
.cols
= DT3155_MAX_COLS
;
978 dts
->config
.rows
= DT3155_MAX_ROWS
;
979 dts
->state
= DT3155_STATE_IDLE
;
981 /* find_PCI() will check if devices are installed; */
982 /* first assume they're not: */
985 dts
->state
= DT3155_STATE_IDLE
;
986 dts
->device_installed
= 0;
989 /* Now let's find the hardware. find_PCI() will set ndevices to the
990 * number of cards found in this machine. */
992 if ((rcode
= find_PCI()) != 0)
994 printk(KERN_INFO
"DT3155 error: find_PCI() failed to find dt3155 board(s)\n");
995 unregister_chrdev(dt3155_major
, "dt3155");
1000 /* Ok, time to setup the frame buffers */
1001 if((rcode
= dt3155_setup_buffers(&allocatorAddr
)) < 0)
1003 printk(KERN_INFO
"DT3155: Error: setting up buffer not large enough.");
1004 unregister_chrdev(dt3155_major
, "dt3155");
1008 /* If we are this far, then there is enough RAM */
1009 /* for the buffers: Print the configuration. */
1010 for( index
= 0; index
< ndevices
; index
++)
1012 dts
= &dt3155_status
[index
];
1014 printk(KERN_INFO
"DT3155: Device = %d; acq_mode = %d;"
1015 "continuous = %d; cols = %d; rows = %d;\n",
1017 dts
->config
.acq_mode
,
1018 dts
->config
.continuous
,
1021 printk(KERN_INFO
"DT3155: m_addr = 0x%x; m_size = %ld;"
1022 "state = %d; device_installed = %d\n",
1024 (long int)dts
->mem_size
,
1026 dts
->device_installed
);
1029 /* Disable ALL interrupts */
1030 for( index
= 0; index
< ndevices
; index
++)
1032 dts
= &dt3155_status
[index
];
1034 writel(0, dt3155_lbase
[index
] + INT_CSR
);
1035 if(dts
->device_installed
)
1038 * This driver *looks* like it can handle sharing interrupts,
1039 * but I can't actually test myself. I've had reports that it
1040 * DOES work so I'll enable it for now. This comment will remain
1041 * as a reminder in case any problems arise. (SS)
1043 /* in older kernels flags are: SA_SHIRQ | SA_INTERRUPT */
1044 rcode
= request_irq(dts
->irq
, (void *)dt3155_isr
,
1045 IRQF_SHARED
| IRQF_DISABLED
, devname
[index
],
1049 printk(KERN_INFO
"DT3155: minor %d request_irq failed for IRQ %d\n",
1051 unregister_chrdev(dt3155_major
, "dt3155");
1057 printk(KERN_INFO
"DT3155: finished loading\n");
1062 static void __exit
dt3155_exit(void)
1064 struct dt3155_status
*dts
;
1067 printk(KERN_INFO
"DT3155: dt3155_exit called\n");
1069 /* removed DMA allocated with the allocator */
1070 #ifdef STANDALONE_ALLOCATOR
1071 if (allocatorAddr
!= 0)
1072 allocator_free_dma(allocatorAddr
);
1074 allocator_cleanup();
1077 unregister_chrdev(dt3155_major
, "dt3155");
1079 for(index
= 0; index
< ndevices
; index
++)
1081 dts
= &dt3155_status
[index
];
1082 if(dts
->device_installed
== 1)
1084 printk(KERN_INFO
"DT3155: Freeing irq %d for device %d\n",
1086 free_irq(dts
->irq
, (void *)dts
);
1091 module_init(dt3155_init
);
1092 module_exit(dt3155_exit
);