2 * Brontes PCI frame grabber driver
4 * Copyright (C) 2008 3M Company
5 * Contact: Justin Bronder <jsbronder@brontes3d.com>
6 * Original Authors: Daniel Drake <ddrake@brontes3d.com>
7 * Duane Griffin <duaneg@dghda.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <linux/device.h>
26 #include <linux/interrupt.h>
27 #include <linux/spinlock.h>
28 #include <linux/ioctl.h>
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/pci.h>
32 #include <linux/types.h>
33 #include <linux/cdev.h>
34 #include <linux/list.h>
35 #include <linux/poll.h>
36 #include <linux/wait.h>
38 #include <linux/uaccess.h>
40 static unsigned int b3dfg_nbuf
= 2;
42 module_param_named(buffer_count
, b3dfg_nbuf
, uint
, 0444);
44 MODULE_PARM_DESC(buffer_count
, "Number of buffers (min 2, default 2)");
46 MODULE_AUTHOR("Daniel Drake <ddrake@brontes3d.com>");
47 MODULE_DESCRIPTION("Brontes frame grabber driver");
48 MODULE_LICENSE("GPL");
50 #define DRIVER_NAME "b3dfg"
51 #define B3DFG_MAX_DEVS 4
52 #define B3DFG_FRAMES_PER_BUFFER 3
54 #define B3DFG_BAR_REGS 0
55 #define B3DFG_REGS_LENGTH 0x10000
57 #define B3DFG_IOC_MAGIC 0xb3 /* dfg :-) */
58 #define B3DFG_IOCGFRMSZ _IOR(B3DFG_IOC_MAGIC, 1, int)
59 #define B3DFG_IOCTNUMBUFS _IO(B3DFG_IOC_MAGIC, 2)
60 #define B3DFG_IOCTTRANS _IO(B3DFG_IOC_MAGIC, 3)
61 #define B3DFG_IOCTQUEUEBUF _IO(B3DFG_IOC_MAGIC, 4)
62 #define B3DFG_IOCTPOLLBUF _IOWR(B3DFG_IOC_MAGIC, 5, struct b3dfg_poll)
63 #define B3DFG_IOCTWAITBUF _IOWR(B3DFG_IOC_MAGIC, 6, struct b3dfg_wait)
64 #define B3DFG_IOCGWANDSTAT _IOR(B3DFG_IOC_MAGIC, 7, int)
67 /* number of 4kb pages per frame */
68 B3D_REG_FRM_SIZE
= 0x0,
70 /* bit 0: set to enable interrupts
71 * bit 1: set to enable cable status change interrupts */
72 B3D_REG_HW_CTRL
= 0x4,
74 /* bit 0-1 - 1-based ID of next pending frame transfer (0 = none)
75 * bit 2 indicates the previous DMA transfer has completed
76 * bit 3 indicates wand cable status change
77 * bit 8:15 - counter of number of discarded triplets */
78 B3D_REG_DMA_STS
= 0x8,
80 /* bit 0: wand status (1 = present, 0 = disconnected) */
81 B3D_REG_WAND_STS
= 0xc,
83 /* bus address for DMA transfers. lower 2 bits must be zero because DMA
84 * works with 32 bit word size. */
85 B3D_REG_EC220_DMA_ADDR
= 0x8000,
87 /* bit 20:0 - number of 32 bit words to be transferred
88 * bit 21:31 - reserved */
89 B3D_REG_EC220_TRF_SIZE
= 0x8004,
92 * bit 1 - interrupt bit (set to generate interrupt at end of transfer)
93 * bit 2 - start bit (set to start transfer)
94 * bit 3 - direction (0 = DMA_TO_DEVICE, 1 = DMA_FROM_DEVICE
95 * bit 4:31 - reserved */
96 B3D_REG_EC220_DMA_STS
= 0x8008,
99 enum b3dfg_buffer_state
{
100 B3DFG_BUFFER_POLLED
= 0,
101 B3DFG_BUFFER_PENDING
,
102 B3DFG_BUFFER_POPULATED
,
105 struct b3dfg_buffer
{
106 unsigned char *frame
[B3DFG_FRAMES_PER_BUFFER
];
107 struct list_head list
;
113 /* no protection needed: all finalized at initialization time */
114 struct pci_dev
*pdev
;
118 unsigned int frame_size
;
121 * Protects buffer state, including buffer_queue, triplet_ready,
122 * cur_dma_frame_idx & cur_dma_frame_addr.
124 spinlock_t buffer_lock
;
125 struct b3dfg_buffer
*buffers
;
126 struct list_head buffer_queue
;
128 /* Last frame in triplet transferred (-1 if none). */
129 int cur_dma_frame_idx
;
131 /* Current frame's address for DMA. */
132 dma_addr_t cur_dma_frame_addr
;
135 * Protects cstate_tstamp.
136 * Nests inside buffer_lock.
138 spinlock_t cstate_lock
;
139 unsigned long cstate_tstamp
;
142 * Protects triplets_dropped.
143 * Nests inside buffers_lock.
145 spinlock_t triplets_dropped_lock
;
146 unsigned int triplets_dropped
;
148 wait_queue_head_t buffer_waitqueue
;
150 unsigned int transmission_enabled
:1;
151 unsigned int triplet_ready
:1;
154 static u8 b3dfg_devices
[B3DFG_MAX_DEVS
];
156 static struct class *b3dfg_class
;
157 static dev_t b3dfg_devt
;
159 static const struct pci_device_id b3dfg_ids
[] __devinitdata
= {
160 { PCI_DEVICE(0x0b3d, 0x0001) },
164 MODULE_DEVICE_TABLE(pci
, b3dfg_ids
);
166 /***** user-visible types *****/
170 unsigned int triplets_dropped
;
175 unsigned int timeout
;
176 unsigned int triplets_dropped
;
179 /**** register I/O ****/
181 static u32
b3dfg_read32(struct b3dfg_dev
*fgdev
, u16 reg
)
183 return ioread32(fgdev
->regs
+ reg
);
186 static void b3dfg_write32(struct b3dfg_dev
*fgdev
, u16 reg
, u32 value
)
188 iowrite32(value
, fgdev
->regs
+ reg
);
191 /**** buffer management ****/
194 * Program EC220 for transfer of a specific frame.
195 * Called with buffer_lock held.
197 static int setup_frame_transfer(struct b3dfg_dev
*fgdev
,
198 struct b3dfg_buffer
*buf
, int frame
)
200 unsigned char *frm_addr
;
201 dma_addr_t frm_addr_dma
;
202 unsigned int frm_size
= fgdev
->frame_size
;
204 frm_addr
= buf
->frame
[frame
];
205 frm_addr_dma
= pci_map_single(fgdev
->pdev
, frm_addr
,
206 frm_size
, PCI_DMA_FROMDEVICE
);
207 if (pci_dma_mapping_error(fgdev
->pdev
, frm_addr_dma
))
210 fgdev
->cur_dma_frame_addr
= frm_addr_dma
;
211 fgdev
->cur_dma_frame_idx
= frame
;
213 b3dfg_write32(fgdev
, B3D_REG_EC220_DMA_ADDR
,
214 cpu_to_le32(frm_addr_dma
));
215 b3dfg_write32(fgdev
, B3D_REG_EC220_TRF_SIZE
,
216 cpu_to_le32(frm_size
>> 2));
217 b3dfg_write32(fgdev
, B3D_REG_EC220_DMA_STS
, 0xf);
222 /* Caller should hold buffer lock */
223 static void dequeue_all_buffers(struct b3dfg_dev
*fgdev
)
226 for (i
= 0; i
< b3dfg_nbuf
; i
++) {
227 struct b3dfg_buffer
*buf
= &fgdev
->buffers
[i
];
228 buf
->state
= B3DFG_BUFFER_POLLED
;
229 list_del_init(&buf
->list
);
233 /* queue a buffer to receive data */
234 static int queue_buffer(struct b3dfg_dev
*fgdev
, int bufidx
)
236 struct device
*dev
= &fgdev
->pdev
->dev
;
237 struct b3dfg_buffer
*buf
;
241 spin_lock_irqsave(&fgdev
->buffer_lock
, flags
);
242 if (bufidx
< 0 || bufidx
>= b3dfg_nbuf
) {
243 dev_dbg(dev
, "Invalid buffer index, %d\n", bufidx
);
247 buf
= &fgdev
->buffers
[bufidx
];
249 if (unlikely(buf
->state
== B3DFG_BUFFER_PENDING
)) {
250 dev_dbg(dev
, "buffer %d is already queued\n", bufidx
);
255 buf
->state
= B3DFG_BUFFER_PENDING
;
256 list_add_tail(&buf
->list
, &fgdev
->buffer_queue
);
258 if (fgdev
->transmission_enabled
&& fgdev
->triplet_ready
) {
259 dev_dbg(dev
, "triplet is ready, pushing immediately\n");
260 fgdev
->triplet_ready
= 0;
261 r
= setup_frame_transfer(fgdev
, buf
, 0);
263 dev_err(dev
, "unable to map DMA buffer\n");
267 spin_unlock_irqrestore(&fgdev
->buffer_lock
, flags
);
271 /* non-blocking buffer poll. returns 1 if data is present in the buffer,
273 static int poll_buffer(struct b3dfg_dev
*fgdev
, void __user
*arg
)
275 struct device
*dev
= &fgdev
->pdev
->dev
;
277 struct b3dfg_buffer
*buf
;
282 if (copy_from_user(&p
, arg
, sizeof(p
)))
285 if (unlikely(!fgdev
->transmission_enabled
)) {
286 dev_dbg(dev
, "cannot poll, transmission disabled\n");
290 if (p
.buffer_idx
< 0 || p
.buffer_idx
>= b3dfg_nbuf
)
293 buf
= &fgdev
->buffers
[p
.buffer_idx
];
295 spin_lock_irqsave(&fgdev
->buffer_lock
, flags
);
297 if (likely(buf
->state
== B3DFG_BUFFER_POPULATED
)) {
299 buf
->state
= B3DFG_BUFFER_POLLED
;
301 /* IRQs already disabled by spin_lock_irqsave above. */
302 spin_lock(&fgdev
->triplets_dropped_lock
);
303 p
.triplets_dropped
= fgdev
->triplets_dropped
;
304 fgdev
->triplets_dropped
= 0;
305 spin_unlock(&fgdev
->triplets_dropped_lock
);
310 spin_unlock_irqrestore(&fgdev
->buffer_lock
, flags
);
312 if (arg_out
&& copy_to_user(arg
, &p
, sizeof(p
)))
318 static unsigned long get_cstate_change(struct b3dfg_dev
*fgdev
)
320 unsigned long flags
, when
;
322 spin_lock_irqsave(&fgdev
->cstate_lock
, flags
);
323 when
= fgdev
->cstate_tstamp
;
324 spin_unlock_irqrestore(&fgdev
->cstate_lock
, flags
);
328 static int is_event_ready(struct b3dfg_dev
*fgdev
, struct b3dfg_buffer
*buf
,
334 spin_lock_irqsave(&fgdev
->buffer_lock
, flags
);
335 spin_lock(&fgdev
->cstate_lock
);
336 result
= (!fgdev
->transmission_enabled
||
337 buf
->state
== B3DFG_BUFFER_POPULATED
||
338 when
!= fgdev
->cstate_tstamp
);
339 spin_unlock(&fgdev
->cstate_lock
);
340 spin_unlock_irqrestore(&fgdev
->buffer_lock
, flags
);
345 /* sleep until a specific buffer becomes populated */
346 static int wait_buffer(struct b3dfg_dev
*fgdev
, void __user
*arg
)
348 struct device
*dev
= &fgdev
->pdev
->dev
;
350 struct b3dfg_buffer
*buf
;
351 unsigned long flags
, when
;
354 if (copy_from_user(&w
, arg
, sizeof(w
)))
357 if (!fgdev
->transmission_enabled
) {
358 dev_dbg(dev
, "cannot wait, transmission disabled\n");
362 if (w
.buffer_idx
< 0 || w
.buffer_idx
>= b3dfg_nbuf
)
365 buf
= &fgdev
->buffers
[w
.buffer_idx
];
367 spin_lock_irqsave(&fgdev
->buffer_lock
, flags
);
369 if (buf
->state
== B3DFG_BUFFER_POPULATED
) {
371 goto out_triplets_dropped
;
374 spin_unlock_irqrestore(&fgdev
->buffer_lock
, flags
);
376 when
= get_cstate_change(fgdev
);
378 r
= wait_event_interruptible_timeout(fgdev
->buffer_waitqueue
,
379 is_event_ready(fgdev
, buf
, when
),
380 (w
.timeout
* HZ
) / 1000);
385 w
.timeout
= r
* 1000 / HZ
;
387 r
= wait_event_interruptible(fgdev
->buffer_waitqueue
,
388 is_event_ready(fgdev
, buf
, when
));
396 /* TODO: Inform the user via field(s) in w? */
397 if (!fgdev
->transmission_enabled
|| when
!= get_cstate_change(fgdev
)) {
402 spin_lock_irqsave(&fgdev
->buffer_lock
, flags
);
404 if (buf
->state
!= B3DFG_BUFFER_POPULATED
) {
409 buf
->state
= B3DFG_BUFFER_POLLED
;
411 out_triplets_dropped
:
413 /* IRQs already disabled by spin_lock_irqsave above. */
414 spin_lock(&fgdev
->triplets_dropped_lock
);
415 w
.triplets_dropped
= fgdev
->triplets_dropped
;
416 fgdev
->triplets_dropped
= 0;
417 spin_unlock(&fgdev
->triplets_dropped_lock
);
420 spin_unlock_irqrestore(&fgdev
->buffer_lock
, flags
);
421 if (copy_to_user(arg
, &w
, sizeof(w
)))
427 /* mmap page fault handler */
428 static int b3dfg_vma_fault(struct vm_area_struct
*vma
,
429 struct vm_fault
*vmf
)
431 struct b3dfg_dev
*fgdev
= vma
->vm_file
->private_data
;
432 unsigned long off
= vmf
->pgoff
<< PAGE_SHIFT
;
433 unsigned int frame_size
= fgdev
->frame_size
;
434 unsigned int buf_size
= frame_size
* B3DFG_FRAMES_PER_BUFFER
;
437 /* determine which buffer the offset lies within */
438 unsigned int buf_idx
= off
/ buf_size
;
439 /* and the offset into the buffer */
440 unsigned int buf_off
= off
% buf_size
;
442 /* determine which frame inside the buffer the offset lies in */
443 unsigned int frm_idx
= buf_off
/ frame_size
;
444 /* and the offset into the frame */
445 unsigned int frm_off
= buf_off
% frame_size
;
447 if (unlikely(buf_idx
>= b3dfg_nbuf
))
448 return VM_FAULT_SIGBUS
;
450 addr
= fgdev
->buffers
[buf_idx
].frame
[frm_idx
] + frm_off
;
451 vm_insert_pfn(vma
, (unsigned long)vmf
->virtual_address
,
452 virt_to_phys(addr
) >> PAGE_SHIFT
);
454 return VM_FAULT_NOPAGE
;
457 static struct vm_operations_struct b3dfg_vm_ops
= {
458 .fault
= b3dfg_vma_fault
,
461 static int get_wand_status(struct b3dfg_dev
*fgdev
, int __user
*arg
)
463 u32 wndstat
= b3dfg_read32(fgdev
, B3D_REG_WAND_STS
);
464 dev_dbg(&fgdev
->pdev
->dev
, "wand status %x\n", wndstat
);
465 return __put_user(wndstat
& 0x1, arg
);
468 static int enable_transmission(struct b3dfg_dev
*fgdev
)
472 struct device
*dev
= &fgdev
->pdev
->dev
;
474 dev_dbg(dev
, "enable transmission\n");
476 /* check the cable is plugged in. */
477 if (!b3dfg_read32(fgdev
, B3D_REG_WAND_STS
)) {
478 dev_dbg(dev
, "cannot start transmission without wand\n");
483 * Check we're a bus master.
484 * TODO: I think we can remove this having added the pci_set_master call
486 pci_read_config_word(fgdev
->pdev
, PCI_COMMAND
, &command
);
487 if (!(command
& PCI_COMMAND_MASTER
)) {
488 dev_err(dev
, "not a bus master, force-enabling\n");
489 pci_write_config_word(fgdev
->pdev
, PCI_COMMAND
,
490 command
| PCI_COMMAND_MASTER
);
493 spin_lock_irqsave(&fgdev
->buffer_lock
, flags
);
495 /* Handle racing enable_transmission calls. */
496 if (fgdev
->transmission_enabled
) {
497 spin_unlock_irqrestore(&fgdev
->buffer_lock
, flags
);
501 spin_lock(&fgdev
->triplets_dropped_lock
);
502 fgdev
->triplets_dropped
= 0;
503 spin_unlock(&fgdev
->triplets_dropped_lock
);
505 fgdev
->triplet_ready
= 0;
506 fgdev
->cur_dma_frame_idx
= -1;
507 fgdev
->transmission_enabled
= 1;
509 spin_unlock_irqrestore(&fgdev
->buffer_lock
, flags
);
511 /* Enable DMA and cable status interrupts. */
512 b3dfg_write32(fgdev
, B3D_REG_HW_CTRL
, 0x03);
518 static void disable_transmission(struct b3dfg_dev
*fgdev
)
520 struct device
*dev
= &fgdev
->pdev
->dev
;
524 dev_dbg(dev
, "disable transmission\n");
526 /* guarantee that no more interrupts will be serviced */
527 spin_lock_irqsave(&fgdev
->buffer_lock
, flags
);
528 fgdev
->transmission_enabled
= 0;
530 b3dfg_write32(fgdev
, B3D_REG_HW_CTRL
, 0);
532 /* FIXME: temporary debugging only. if the board stops transmitting,
533 * hitting ctrl+c and seeing this message is useful for determining
534 * the state of the board. */
535 tmp
= b3dfg_read32(fgdev
, B3D_REG_DMA_STS
);
536 dev_dbg(dev
, "DMA_STS reads %x after TX stopped\n", tmp
);
538 dequeue_all_buffers(fgdev
);
539 spin_unlock_irqrestore(&fgdev
->buffer_lock
, flags
);
541 wake_up_interruptible(&fgdev
->buffer_waitqueue
);
544 static int set_transmission(struct b3dfg_dev
*fgdev
, int enabled
)
548 if (enabled
&& !fgdev
->transmission_enabled
)
549 res
= enable_transmission(fgdev
);
550 else if (!enabled
&& fgdev
->transmission_enabled
)
551 disable_transmission(fgdev
);
556 /* Called in interrupt context. */
557 static void handle_cstate_unplug(struct b3dfg_dev
*fgdev
)
559 /* Disable all interrupts. */
560 b3dfg_write32(fgdev
, B3D_REG_HW_CTRL
, 0);
562 /* Stop transmission. */
563 spin_lock(&fgdev
->buffer_lock
);
564 fgdev
->transmission_enabled
= 0;
566 fgdev
->cur_dma_frame_idx
= -1;
567 fgdev
->triplet_ready
= 0;
568 if (fgdev
->cur_dma_frame_addr
) {
569 pci_unmap_single(fgdev
->pdev
, fgdev
->cur_dma_frame_addr
,
570 fgdev
->frame_size
, PCI_DMA_FROMDEVICE
);
571 fgdev
->cur_dma_frame_addr
= 0;
573 dequeue_all_buffers(fgdev
);
574 spin_unlock(&fgdev
->buffer_lock
);
577 /* Called in interrupt context. */
578 static void handle_cstate_change(struct b3dfg_dev
*fgdev
)
580 u32 cstate
= b3dfg_read32(fgdev
, B3D_REG_WAND_STS
);
582 struct device
*dev
= &fgdev
->pdev
->dev
;
584 dev_dbg(dev
, "cable state change: %u\n", cstate
);
587 * When the wand is unplugged we reset our state. The hardware will
588 * have done the same internally.
590 * Note we should never see a cable *plugged* event, as interrupts
591 * should only be enabled when transmitting, which requires the cable
592 * to be plugged. If we do see one it probably means the cable has been
593 * unplugged and re-plugged very rapidly. Possibly because it has a
594 * broken wire and is momentarily losing contact.
596 * TODO: At the moment if you plug in the cable then enable transmission
597 * the hardware will raise a couple of spurious interrupts, so
598 * just ignore them for now.
600 * Once the hardware is fixed we should complain and treat it as an
601 * unplug. Or at least track how frequently it is happening and do
602 * so if too many come in.
605 dev_warn(dev
, "ignoring unexpected plug event\n");
608 handle_cstate_unplug(fgdev
);
611 * Record cable state change timestamp & wake anyone waiting
612 * on a cable state change. Be paranoid about ensuring events
613 * are not missed if we somehow get two interrupts in a jiffy.
615 spin_lock(&fgdev
->cstate_lock
);
617 if (when
<= fgdev
->cstate_tstamp
)
618 when
= fgdev
->cstate_tstamp
+ 1;
619 fgdev
->cstate_tstamp
= when
;
620 wake_up_interruptible(&fgdev
->buffer_waitqueue
);
621 spin_unlock(&fgdev
->cstate_lock
);
624 /* Called with buffer_lock held. */
625 static void transfer_complete(struct b3dfg_dev
*fgdev
)
627 struct b3dfg_buffer
*buf
;
628 struct device
*dev
= &fgdev
->pdev
->dev
;
630 pci_unmap_single(fgdev
->pdev
, fgdev
->cur_dma_frame_addr
,
631 fgdev
->frame_size
, PCI_DMA_FROMDEVICE
);
632 fgdev
->cur_dma_frame_addr
= 0;
634 buf
= list_entry(fgdev
->buffer_queue
.next
, struct b3dfg_buffer
, list
);
636 dev_dbg(dev
, "handle frame completion\n");
637 if (fgdev
->cur_dma_frame_idx
== B3DFG_FRAMES_PER_BUFFER
- 1) {
639 /* last frame of that triplet completed */
640 dev_dbg(dev
, "triplet completed\n");
641 buf
->state
= B3DFG_BUFFER_POPULATED
;
642 list_del_init(&buf
->list
);
643 wake_up_interruptible(&fgdev
->buffer_waitqueue
);
648 * Called with buffer_lock held.
650 * Note that idx is the (1-based) *next* frame to be transferred, while
651 * cur_dma_frame_idx is the (0-based) *last* frame to have been transferred (or
652 * -1 if none). Thus there should be a difference of 2 between them.
654 static bool setup_next_frame_transfer(struct b3dfg_dev
*fgdev
, int idx
)
656 struct b3dfg_buffer
*buf
;
657 struct device
*dev
= &fgdev
->pdev
->dev
;
660 dev_dbg(dev
, "program DMA transfer for next frame: %d\n", idx
);
662 buf
= list_entry(fgdev
->buffer_queue
.next
, struct b3dfg_buffer
, list
);
663 if (idx
== fgdev
->cur_dma_frame_idx
+ 2) {
664 if (setup_frame_transfer(fgdev
, buf
, idx
- 1))
665 dev_err(dev
, "unable to map DMA buffer\n");
668 dev_err(dev
, "frame mismatch, got %d, expected %d\n",
669 idx
, fgdev
->cur_dma_frame_idx
+ 2);
671 /* FIXME: handle dropped triplets here */
677 static irqreturn_t
b3dfg_intr(int irq
, void *dev_id
)
679 struct b3dfg_dev
*fgdev
= dev_id
;
680 struct device
*dev
= &fgdev
->pdev
->dev
;
684 irqreturn_t res
= IRQ_HANDLED
;
686 sts
= b3dfg_read32(fgdev
, B3D_REG_DMA_STS
);
687 if (unlikely(sts
== 0)) {
688 dev_warn(dev
, "ignore interrupt, DMA status is 0\n");
693 if (unlikely(!fgdev
->transmission_enabled
)) {
694 dev_warn(dev
, "ignore interrupt, TX disabled\n");
699 /* Handle dropped frames, as reported by the hardware. */
700 dropped
= (sts
>> 8) & 0xff;
701 dev_dbg(dev
, "intr: DMA_STS=%08x (drop=%d comp=%d next=%d)\n",
702 sts
, dropped
, !!(sts
& 0x4), sts
& 0x3);
703 if (unlikely(dropped
> 0)) {
704 spin_lock(&fgdev
->triplets_dropped_lock
);
705 fgdev
->triplets_dropped
+= dropped
;
706 spin_unlock(&fgdev
->triplets_dropped_lock
);
709 /* Handle a cable state change (i.e. the wand being unplugged). */
711 handle_cstate_change(fgdev
);
715 spin_lock(&fgdev
->buffer_lock
);
716 if (unlikely(list_empty(&fgdev
->buffer_queue
))) {
718 /* FIXME need more sanity checking here */
719 dev_info(dev
, "buffer not ready for next transfer\n");
720 fgdev
->triplet_ready
= 1;
724 /* Has a frame transfer been completed? */
726 u32 dma_status
= b3dfg_read32(fgdev
, B3D_REG_EC220_DMA_STS
);
728 /* Check for DMA errors reported by the hardware. */
729 if (unlikely(dma_status
& 0x1)) {
730 dev_err(dev
, "EC220 error: %08x\n", dma_status
);
732 /* FIXME flesh out error handling */
736 /* Sanity check, we should have a frame index at this point. */
737 if (unlikely(fgdev
->cur_dma_frame_idx
== -1)) {
738 dev_err(dev
, "completed but no last idx?\n");
740 /* FIXME flesh out error handling */
744 transfer_complete(fgdev
);
747 /* Is there another frame transfer pending? */
749 need_ack
= setup_next_frame_transfer(fgdev
, sts
& 0x3);
751 fgdev
->cur_dma_frame_idx
= -1;
754 spin_unlock(&fgdev
->buffer_lock
);
757 dev_dbg(dev
, "acknowledging interrupt\n");
758 b3dfg_write32(fgdev
, B3D_REG_EC220_DMA_STS
, 0x0b);
763 static int b3dfg_open(struct inode
*inode
, struct file
*filp
)
765 struct b3dfg_dev
*fgdev
=
766 container_of(inode
->i_cdev
, struct b3dfg_dev
, chardev
);
768 dev_dbg(&fgdev
->pdev
->dev
, "open\n");
769 filp
->private_data
= fgdev
;
773 static int b3dfg_release(struct inode
*inode
, struct file
*filp
)
775 struct b3dfg_dev
*fgdev
= filp
->private_data
;
776 dev_dbg(&fgdev
->pdev
->dev
, "release\n");
777 disable_transmission(fgdev
);
781 static long b3dfg_ioctl(struct file
*filp
, unsigned int cmd
, unsigned long arg
)
783 struct b3dfg_dev
*fgdev
= filp
->private_data
;
786 case B3DFG_IOCGFRMSZ
:
787 return __put_user(fgdev
->frame_size
, (int __user
*) arg
);
788 case B3DFG_IOCGWANDSTAT
:
789 return get_wand_status(fgdev
, (int __user
*) arg
);
790 case B3DFG_IOCTTRANS
:
791 return set_transmission(fgdev
, (int) arg
);
792 case B3DFG_IOCTQUEUEBUF
:
793 return queue_buffer(fgdev
, (int) arg
);
794 case B3DFG_IOCTPOLLBUF
:
795 return poll_buffer(fgdev
, (void __user
*) arg
);
796 case B3DFG_IOCTWAITBUF
:
797 return wait_buffer(fgdev
, (void __user
*) arg
);
799 dev_dbg(&fgdev
->pdev
->dev
, "unrecognised ioctl %x\n", cmd
);
804 static unsigned int b3dfg_poll(struct file
*filp
, poll_table
*poll_table
)
806 struct b3dfg_dev
*fgdev
= filp
->private_data
;
807 unsigned long flags
, when
;
811 when
= get_cstate_change(fgdev
);
812 poll_wait(filp
, &fgdev
->buffer_waitqueue
, poll_table
);
814 spin_lock_irqsave(&fgdev
->buffer_lock
, flags
);
815 for (i
= 0; i
< b3dfg_nbuf
; i
++) {
816 if (fgdev
->buffers
[i
].state
== B3DFG_BUFFER_POPULATED
) {
817 r
= POLLIN
| POLLRDNORM
;
821 spin_unlock_irqrestore(&fgdev
->buffer_lock
, flags
);
823 /* TODO: Confirm this is how we want to communicate the change. */
824 if (!fgdev
->transmission_enabled
|| when
!= get_cstate_change(fgdev
))
830 static int b3dfg_mmap(struct file
*filp
, struct vm_area_struct
*vma
)
832 struct b3dfg_dev
*fgdev
= filp
->private_data
;
833 unsigned long offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
834 unsigned long vsize
= vma
->vm_end
- vma
->vm_start
;
835 unsigned long bufdatalen
= b3dfg_nbuf
* fgdev
->frame_size
* 3;
836 unsigned long psize
= bufdatalen
- offset
;
839 if (vsize
<= psize
) {
840 vma
->vm_flags
|= VM_IO
| VM_RESERVED
| VM_CAN_NONLINEAR
|
842 vma
->vm_ops
= &b3dfg_vm_ops
;
850 static struct file_operations b3dfg_fops
= {
851 .owner
= THIS_MODULE
,
853 .release
= b3dfg_release
,
854 .unlocked_ioctl
= b3dfg_ioctl
,
859 static void free_all_frame_buffers(struct b3dfg_dev
*fgdev
)
862 for (i
= 0; i
< b3dfg_nbuf
; i
++)
863 for (j
= 0; j
< B3DFG_FRAMES_PER_BUFFER
; j
++)
864 kfree(fgdev
->buffers
[i
].frame
[j
]);
865 kfree(fgdev
->buffers
);
868 /* initialize device and any data structures. called before any interrupts
870 static int b3dfg_init_dev(struct b3dfg_dev
*fgdev
)
873 u32 frm_size
= b3dfg_read32(fgdev
, B3D_REG_FRM_SIZE
);
875 /* Disable interrupts. In abnormal circumstances (e.g. after a crash)
876 * the board may still be transmitting from the previous session. If we
877 * ensure that interrupts are disabled before we later enable them, we
878 * are sure to capture a triplet from the start, rather than starting
879 * from frame 2 or 3. Disabling interrupts causes the FG to throw away
880 * all buffered data and stop buffering more until interrupts are
883 b3dfg_write32(fgdev
, B3D_REG_HW_CTRL
, 0);
885 fgdev
->frame_size
= frm_size
* 4096;
886 fgdev
->buffers
= kzalloc(sizeof(struct b3dfg_buffer
) * b3dfg_nbuf
,
890 for (i
= 0; i
< b3dfg_nbuf
; i
++) {
891 struct b3dfg_buffer
*buf
= &fgdev
->buffers
[i
];
892 for (j
= 0; j
< B3DFG_FRAMES_PER_BUFFER
; j
++) {
893 buf
->frame
[j
] = kmalloc(fgdev
->frame_size
, GFP_KERNEL
);
897 INIT_LIST_HEAD(&buf
->list
);
900 INIT_LIST_HEAD(&fgdev
->buffer_queue
);
901 init_waitqueue_head(&fgdev
->buffer_waitqueue
);
902 spin_lock_init(&fgdev
->buffer_lock
);
903 spin_lock_init(&fgdev
->cstate_lock
);
904 spin_lock_init(&fgdev
->triplets_dropped_lock
);
908 free_all_frame_buffers(fgdev
);
913 /* find next free minor number, returns -1 if none are availabile */
914 static int get_free_minor(void)
917 for (i
= 0; i
< B3DFG_MAX_DEVS
; i
++) {
918 if (b3dfg_devices
[i
] == 0)
924 static int __devinit
b3dfg_probe(struct pci_dev
*pdev
,
925 const struct pci_device_id
*id
)
927 struct b3dfg_dev
*fgdev
= kzalloc(sizeof(*fgdev
), GFP_KERNEL
);
929 int minor
= get_free_minor();
930 dev_t devno
= MKDEV(MAJOR(b3dfg_devt
), minor
);
931 unsigned long res_len
;
932 resource_size_t res_base
;
938 dev_err(&pdev
->dev
, "too many devices found!\n");
943 b3dfg_devices
[minor
] = 1;
944 dev_info(&pdev
->dev
, "probe device with IRQ %d\n", pdev
->irq
);
946 cdev_init(&fgdev
->chardev
, &b3dfg_fops
);
947 fgdev
->chardev
.owner
= THIS_MODULE
;
949 r
= cdev_add(&fgdev
->chardev
, devno
, 1);
951 dev_err(&pdev
->dev
, "cannot add char device\n");
952 goto err_release_minor
;
955 fgdev
->dev
= device_create(
959 dev_get_drvdata(&pdev
->dev
),
960 DRIVER_NAME
"%d", minor
);
962 if (IS_ERR(fgdev
->dev
)) {
963 dev_err(&pdev
->dev
, "cannot create device\n");
964 r
= PTR_ERR(fgdev
->dev
);
968 r
= pci_enable_device(pdev
);
970 dev_err(&pdev
->dev
, "cannot enable PCI device\n");
974 res_len
= pci_resource_len(pdev
, B3DFG_BAR_REGS
);
975 if (res_len
!= B3DFG_REGS_LENGTH
) {
976 dev_err(&pdev
->dev
, "invalid register resource size\n");
981 if (pci_resource_flags(pdev
, B3DFG_BAR_REGS
)
982 != (IORESOURCE_MEM
| IORESOURCE_SIZEALIGN
)) {
983 dev_err(&pdev
->dev
, "invalid resource flags\n");
987 r
= pci_request_regions(pdev
, DRIVER_NAME
);
989 dev_err(&pdev
->dev
, "cannot obtain PCI resources\n");
993 pci_set_master(pdev
);
995 r
= pci_set_dma_mask(pdev
, DMA_BIT_MASK(32));
997 dev_err(&pdev
->dev
, "no usable DMA configuration\n");
1001 res_base
= pci_resource_start(pdev
, B3DFG_BAR_REGS
);
1002 fgdev
->regs
= ioremap_nocache(res_base
, res_len
);
1004 dev_err(&pdev
->dev
, "regs ioremap failed\n");
1010 pci_set_drvdata(pdev
, fgdev
);
1011 r
= b3dfg_init_dev(fgdev
);
1013 dev_err(&pdev
->dev
, "failed to initalize device\n");
1017 r
= request_irq(pdev
->irq
, b3dfg_intr
, IRQF_SHARED
, DRIVER_NAME
, fgdev
);
1019 dev_err(&pdev
->dev
, "couldn't request irq %d\n", pdev
->irq
);
1026 free_all_frame_buffers(fgdev
);
1028 iounmap(fgdev
->regs
);
1030 pci_release_regions(pdev
);
1032 pci_disable_device(pdev
);
1034 device_destroy(b3dfg_class
, devno
);
1036 cdev_del(&fgdev
->chardev
);
1038 b3dfg_devices
[minor
] = 0;
1044 static void __devexit
b3dfg_remove(struct pci_dev
*pdev
)
1046 struct b3dfg_dev
*fgdev
= pci_get_drvdata(pdev
);
1047 unsigned int minor
= MINOR(fgdev
->chardev
.dev
);
1049 dev_dbg(&pdev
->dev
, "remove\n");
1051 free_irq(pdev
->irq
, fgdev
);
1052 iounmap(fgdev
->regs
);
1053 pci_release_regions(pdev
);
1054 pci_disable_device(pdev
);
1055 device_destroy(b3dfg_class
, MKDEV(MAJOR(b3dfg_devt
), minor
));
1056 cdev_del(&fgdev
->chardev
);
1057 free_all_frame_buffers(fgdev
);
1059 b3dfg_devices
[minor
] = 0;
1062 static struct pci_driver b3dfg_driver
= {
1063 .name
= DRIVER_NAME
,
1064 .id_table
= b3dfg_ids
,
1065 .probe
= b3dfg_probe
,
1066 .remove
= __devexit_p(b3dfg_remove
),
1069 static int __init
b3dfg_module_init(void)
1073 if (b3dfg_nbuf
< 2) {
1074 printk(KERN_ERR DRIVER_NAME
1075 ": buffer_count is out of range (must be >= 2)");
1079 printk(KERN_INFO DRIVER_NAME
": loaded\n");
1081 b3dfg_class
= class_create(THIS_MODULE
, DRIVER_NAME
);
1082 if (IS_ERR(b3dfg_class
))
1083 return PTR_ERR(b3dfg_class
);
1085 r
= alloc_chrdev_region(&b3dfg_devt
, 0, B3DFG_MAX_DEVS
, DRIVER_NAME
);
1089 r
= pci_register_driver(&b3dfg_driver
);
1096 unregister_chrdev_region(b3dfg_devt
, B3DFG_MAX_DEVS
);
1098 class_destroy(b3dfg_class
);
1102 static void __exit
b3dfg_module_exit(void)
1104 printk(KERN_INFO DRIVER_NAME
": unloaded\n");
1105 pci_unregister_driver(&b3dfg_driver
);
1106 unregister_chrdev_region(b3dfg_devt
, B3DFG_MAX_DEVS
);
1107 class_destroy(b3dfg_class
);
1110 module_init(b3dfg_module_init
);
1111 module_exit(b3dfg_module_exit
);