Staging: dt3155: make module_{init/exit} functions static
[linux-2.6/btrfs-unstable.git] / drivers / staging / dt3155 / dt3155_drv.c
blob73169968a1ff5f4442d860b466aa3c341e03d4e4
1 /*
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,
21 MA 02111-1307 USA
23 -- Changes --
25 Date Programmer Description of changes made
26 -------------------------------------------------------------------
27 03-Jul-2000 JML n/a
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.
41 -- Notes --
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>
66 #include <linux/io.h>
68 #include <linux/uaccess.h>
70 #include "dt3155.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);
81 int dt3155_errno = 0;
83 #ifndef PCI_DEVICE_ID_INTEL_7116
84 #define PCI_DEVICE_ID_INTEL_7116 0x1223
85 #endif
87 #define DT3155_VENDORID PCI_VENDOR_ID_INTEL
88 #define DT3155_DEVICEID PCI_DEVICE_ID_INTEL_7116
89 #define MAXPCI 16
91 #ifdef DT_DEBUG
92 #define DT_3155_DEBUG_MSG(x,y) printk(x,y)
93 #else
94 #define DT_3155_DEBUG_MSG(x,y)
95 #endif
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
116 #if MAXBOARDS == 2
117 , NULL
118 #endif
121 u32 dt3155_dev_open[MAXBOARDS] = {0
122 #if MAXBOARDS == 2
124 #endif
127 u32 ndevices = 0;
128 u32 unique_tag = 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.
134 * (James Rose)
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
142 #if 1
143 INT_CSR_R int_csr_r;
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;
156 #else
157 dts->state |= DT3155_STATE_STOP;
158 fb->stop_acquire = 1;
159 #endif
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)
173 int minor = -1;
174 int index;
175 unsigned long flags;
176 u32 buffer_addr;
177 void __iomem *mmio;
178 struct dt3155_status *dts;
179 struct dt3155_fbuffer *fb;
180 INT_CSR_R int_csr_r;
181 CSR1_R csr1_r;
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])
189 minor = index;
190 break;
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");
197 return;
200 mmio = dt3155_lbase[minor];
201 dts = &dt3155_status[minor];
202 fb = &dts->fbuffer;
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");
214 return;
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)
224 fb->frame_count++;
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;
241 else
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);
258 local_irq_disable();
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);
280 return;
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)
294 fb->frame_count++;
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);
313 else
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);
329 local_irq_disable();
331 #ifdef DEBUG_QUES_B
332 printques(fb);
333 #endif
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);
365 else
366 { /* no empty or locked buffers, so use a readybuf */
367 fb->active_buf = pop_ready(fb);
372 #ifdef DEBUG_QUES_B
373 printques(fb);
374 #endif
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);
390 else
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);
404 return;
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;
423 CSR1_R csr1_r;
424 INT_CSR_R int_csr_r;
425 I2C_CSR2 i2c_csr2;
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);
434 break;
437 case DT3155_STATE_FRAME:
438 default:
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);
444 break;
448 /* 50/60 Hz should be set before this point but let's make sure it is */
449 /* right anyway */
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 */
458 * TODO:
459 * shouldn't we be concered with continuous values of
460 * DT3155_SNAP & DT3155_ACQ here? (SS)
463 csr1_r.reg = 0;
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 */
477 int_csr_r.reg = 0;
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!! */
493 return;
497 /*****************************************************
498 * ioctl()
500 *****************************************************/
501 static int dt3155_ioctl(struct inode *inode,
502 struct file *file,
503 unsigned int cmd,
504 unsigned long arg)
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)
512 return -ENODEV;
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);
524 return -EINVAL;
527 switch (cmd)
529 case DT3155_SET_CONFIG:
531 if (dts->state != DT3155_STATE_IDLE)
532 return -EBUSY;
535 struct dt3155_config tmp;
536 if (copy_from_user(&tmp, up, sizeof(tmp)))
537 return -EFAULT;
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))
546 return -EINVAL;
548 dts->config = tmp;
550 return 0;
552 case DT3155_GET_CONFIG:
554 if (copy_to_user(up, dts, sizeof(*dts)))
555 return -EFAULT;
556 return 0;
558 case DT3155_FLUSH: /* Flushes the buffers -- ensures fresh data */
560 if (dts->state != DT3155_STATE_IDLE)
561 return -EBUSY;
562 return dt3155_flush(fb);
564 case DT3155_STOP:
566 if (dts->state & DT3155_STATE_STOP || fb->stop_acquire)
567 return -EBUSY;
569 if (dts->state == DT3155_STATE_IDLE)
570 return 0;
572 quick_stop(minor);
573 if (copy_to_user(up, dts, sizeof(*dts)))
574 return -EFAULT;
575 return 0;
577 case DT3155_START:
579 if (dts->state != DT3155_STATE_IDLE)
580 return -EBUSY;
582 fb->stop_acquire = 0;
583 fb->frame_count = 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;
590 else
592 dts->state = DT3155_STATE_FRAME;
595 dt3155_init_isr(minor);
596 if (copy_to_user(up, dts, sizeof(*dts)))
597 return -EFAULT;
598 return 0;
600 default:
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);
607 return -ENOSYS;
610 return -ENOSYS;
613 /*****************************************************
614 * mmap()
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,
643 vma->vm_start,
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");
648 return -EAGAIN;
651 else
653 printk(KERN_INFO "DT3155: dt3155_mmap() bad call.\n");
654 return -ENXIO;
657 return 0;
661 /*****************************************************
662 * open()
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");
676 return -EBUSY;
679 if (dts->device_installed==0)
681 printk(KERN_INFO "DT3155 Open Error: No such device dt3155 minor number %d\n",
682 minor);
683 return -EIO;
686 if (dts->state != DT3155_STATE_IDLE) {
687 printk(KERN_INFO "DT3155: Not in idle state (state = %x)\n",
688 dts->state);
689 return -EBUSY;
692 printk(KERN_INFO "DT3155: Device opened.\n");
694 dt3155_dev_open[minor] = 1 ;
696 dt3155_flush(fb);
698 /* Disable ALL interrupts */
699 writel(0, dt3155_lbase[minor] + INT_CSR);
701 init_waitqueue_head(&(dt3155_read_wait_queue[minor]));
703 return 0;
707 /*****************************************************
708 * close()
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");
722 else
724 dt3155_dev_open[minor] = 0;
726 if (dts->state != DT3155_STATE_IDLE)
728 quick_stop(minor);
731 return 0;
734 /*****************************************************
735 * read()
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);
743 u32 offset;
744 int frame_index;
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");
754 return -EINVAL;
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)*/
766 /* return -EBUSY;*/
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"); */
773 /* printques(fb); */
774 return -EAGAIN;
777 else
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);
787 if (frame_index < 0)
789 printk(KERN_INFO "DT3155: read: interrupted\n");
790 quick_stop (minor);
791 printques(fb);
792 return -EINTR;
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);
802 buf += sizeof(u32);
803 put_user(fb->frame_count, (unsigned int __user *)buf);
804 buf += sizeof(u32);
805 put_user(dts->state, (unsigned int __user *)buf);
806 buf += sizeof(u32);
807 if (copy_to_user(buf, frame_info, sizeof(*frame_info)))
808 return -EFAULT;
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);
824 return 0;
827 static long
828 dt3155_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
830 int ret;
832 mutex_lock(&dt3155_mutex);
833 ret = dt3155_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
834 mutex_unlock(&dt3155_mutex);
836 return ret;
839 /*****************************************************
840 * file operations supported by DT3155 driver
841 * needed by dt3155_init
842 * register_chrdev
843 *****************************************************/
844 static struct file_operations dt3155_fops = {
845 .read = dt3155_read,
846 .unlocked_ioctl = dt3155_unlocked_ioctl,
847 .mmap = dt3155_mmap,
848 .poll = dt3155_poll,
849 .open = dt3155_open,
850 .release = dt3155_close
854 /*****************************************************
855 * find_PCI();
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;
865 unsigned long base;
866 unsigned char irq;
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? */
874 if ((error =
875 pci_read_config_word(pci_dev, PCI_CLASS_DEVICE, &rev_device)))
876 continue;
878 /* Found a board */
879 DT_3155_DEBUG_MSG("DT3155: Device number %d \n", pci_index);
881 /* Make sure the driver was compiled with enough buffers to handle
882 this many boards */
883 if (pci_index > MAXBOARDS) {
884 printk(KERN_ERR "DT3155: Found %d devices, but driver only configured "
885 "for %d devices\n"
886 "DT3155: Please change MAXBOARDS in dt3155.h\n",
887 pci_index, MAXBOARDS);
888 goto err;
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,
894 (u32 *) &base)))
896 printk(KERN_INFO "DT3155: Was not able to find device\n");
897 goto err;
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
904 * can access it. */
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");
912 goto err;
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");
918 goto err;
921 DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq);
922 dts->irq = 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",
926 pci_index,
927 dts->irq,
928 dt3155_lbase[pci_index-1]);
931 ndevices = pci_index;
933 return 0;
935 err:
936 pci_dev_put(pci_dev);
937 return -EIO;
940 u32 allocatorAddr = 0;
943 static int __init dt3155_init(void)
945 struct dt3155_status *dts;
946 int index;
947 int rcode = 0;
948 char *devname[MAXBOARDS];
950 devname[0] = "dt3155a";
951 #if MAXBOARDS == 2
952 devname[1] = "dt3155b";
953 #endif
955 printk(KERN_INFO "DT3155: Loading module...\n");
957 /* Register the device driver */
958 rcode = register_chrdev(dt3155_major, "dt3155", &dt3155_fops);
959 if(rcode < 0)
961 printk(KERN_INFO "DT3155: register_chrdev failed \n");
962 return rcode;
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: */
983 dts->mem_addr = 0;
984 dts->mem_size = 0;
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");
996 return rcode;
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");
1005 return rcode;
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",
1016 index ,
1017 dts->config.acq_mode,
1018 dts->config.continuous,
1019 dts->config.cols,
1020 dts->config.rows);
1021 printk(KERN_INFO "DT3155: m_addr = 0x%x; m_size = %ld;"
1022 "state = %d; device_installed = %d\n",
1023 dts->mem_addr,
1024 (long int)dts->mem_size,
1025 dts->state,
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],
1046 (void *)dts);
1047 if(rcode < 0)
1049 printk(KERN_INFO "DT3155: minor %d request_irq failed for IRQ %d\n",
1050 index, dts->irq);
1051 unregister_chrdev(dt3155_major, "dt3155");
1052 return rcode;
1057 printk(KERN_INFO "DT3155: finished loading\n");
1059 return 0;
1062 static void __exit dt3155_exit(void)
1064 struct dt3155_status *dts;
1065 int index;
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);
1073 #else
1074 allocator_cleanup();
1075 #endif
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",
1085 dts->irq, index);
1086 free_irq(dts->irq, (void *)dts);
1091 module_init(dt3155_init);
1092 module_exit(dt3155_exit);