1 /*
2 * hrt.c
3 *
4 * last updated - 17 June 2005
5 * Atulya Mahajan / Sean Toh
6 *
7
8
9 This is a device driver for the PixelSmart512-8 (greyscale)
10 and Video Gala (color) framegrabbers.
11 For more information on these devices, see http://www.pixelsmart.com.
12
13 This driver is produced as a course project for the 'linux kernel programming'
14 course at the Florida State University, as a term project submitted by the team
15 comprising of Atulya Mahajan and Sean Toh, in the summer of 2005.
16
17 This driver carries forward the work done by other teams in the last 2 years
18 by Brett W. Thompson, Gilberto Morejon, Veena Adityan, Arthi Gokarn and
19 Alex Rudnick under the guidance of Dr Ted Baker.
20
21 This driver supports the following features
22 1. Support for the greyscale as well as color frame grabber cards
23 2. Support for interrupt driven I/O
24 3. Support for streaming I/O from color/grey scale devices
25 4. Automatic detection of the type of device present
26
27 */
28
29 #ifndef __KERNEL__
30 #define __KERNEL__
31 #endif
32
33 #include <linux/config.h>
34 #include <linux/delay.h> /* udelay */
35 #include <linux/errno.h> /* error codes */
36 #include <linux/file.h>
37 #include <linux/fs.h>
38 #include <linux/interrupt.h>
39 #include <linux/ioport.h>
40 #include <linux/kernel.h>
41 #include <linux/mm.h>
42 #include <linux/module.h>
43 #include <linux/pci.h>
44 #include <linux/proc_fs.h>
45 #include <linux/sched.h>
46 #include <linux/slab.h>
47 #include <linux/spinlock.h>
48 #include <linux/version.h>
49
50 #include <linux/config.h>
51 #include <linux/moduleparam.h>
52
53 #include <linux/interrupt.h>
54
55 #include <asm/io.h>
56 #include <asm/segment.h>
57 #include <asm/uaccess.h>
58
59 #include <linux/videodev.h>
60
61 #include "hrt.h"
62
63 #ifndef HAVE_V4L2
64 # error Sorry, this module requires v4l2. You should patch your kernel with v4l2 or you could download the non-v4l2 dependent module hrtmem.c.
65 #endif
66
67
68 #define HRT_DEBUG
69
70 #define HRT_ERROR_MSG(args...) do{printk("<1>hrt: "); printk(args);\
71 printk("\n");}while(0)
72
73 /*********************
74 * Module Parameters *
75 *********************/
76
77 #ifndef module_param
78 #define hrt_parm(name, pstr, type, perm) MODULE_PARM(name, pstr)
79 #else
80 #define hrt_parm(name, pstr, type, perm) module_param(name, type, perm)
81 #endif
82
83 static
84 int major_number = 82;
85 hrt_parm(major_number, "i", int, 0);
86
87 #ifndef HRT_MAX_DEVICES
88 #define HRT_MAX_DEVICES 4
89 #endif
90
91 #ifndef HRT_IO_SIZE
92 #define HRT_IO_SIZE 0x4000
93 #endif
94
95 /********************************************************************/
96 /**
97 * hrt_ctls - controls the user can set via V4L ioctl's
98 */
99 static const struct v4l2_queryctrl hrt_ctls[] = {
100 {
101 .id = V4L2_CID_BRIGHTNESS,
102 .name = "Brightness",
103 .minimum = 0,
104 .maximum = 255,
105 .step = 1,
106 .default_value = 0x9b, // (decimal: 155)
107 .type = V4L2_CTRL_TYPE_INTEGER,
108 },
109 {
110 .id = V4L2_CID_CONTRAST,
111 .name = "Contrast",
112 .minimum = 0,
113 .maximum = 255,
114 .step = 1,
115 .default_value = 0x5e, // (decimal: 94)
116 .type = V4L2_CTRL_TYPE_INTEGER,
117 }
118 };
119
120
121 /********************************************************************/
122 /**
123 * hrt_addresses - a list of possible jumper-selected addresses
124 * jumper A on = plug and play address (above one MB address)
125 * jumper A off = hardwired to 0xdc000 or 0xd4000
126 * jumper B on = address 0xd4000 (ignored if jumper A is on)
127 * jumper B off = address 0xdc000 (ignored if jumper A is on)
128 */
129 const unsigned long hrt_addresses[] = { 0xd4000, 0xdc000 };
130
131 /***************************
132 * Card-specific constants *
133 ***************************/
134
135 #define HRT_VENDOR_ID 0x0004
136 #define HRT_DEVICE_ID_GREY 0x0404
137 #define HRT_DEVICE_ID_COLOR 0x0408
138
139 /* Number of registers on the board- checked in i2c_init() */
140 #define HRT_SAA7110_MAXREG 0x34
141
142
143 /********************************************************************/
144 /**
145 * struct stream_buffer - represents a single buffer for streaming
146 */
147 struct stream_buffer {
148 struct v4l2_buffer vidbuf; /* For the V4L ioctl's */
149 int fields_grabbed; /* Two-bit pair of flags indicating which fields
150 have been grabbed (i.e., 00 = no fields,
151 11 = both) */
152 struct list_head node; /* Connection into queues */
153 int requested; /* Set by REQBUF ioctl */
154 unsigned char *vaddress; /* This is the pointer to the vmalloc()'d
155 memory into which the actual frame goes */
156 int vma_refcount; /* Reference count */
157 };
158
159
160 /********************************************************************/
161 /**
162 * struct stream_buffer_queue - FIFO of stream_buffer structs
163 */
164 struct stream_buffer_queue {
165 struct stream_buffer *streambuf; /* Pointer to node data */
166 struct list_head head; /* Start of the queue */
167 rwlock_t lock; /* Lock to protect the queue */
168 int length; /* How many nodes are on the queue */
169 };
170
171
172 /********************************************************************/
173 /**
174 * HRT device descriptor
175 */
176 typedef struct {
177 int num;
178 int state;
179 /* minor device number, index in hrt_devices[] */
180 unsigned long virt_addr;
181 unsigned long phys_addr;
182 /* cannot be opened again until released */
183
184 /* spinlock and is_locked control access to the device */
185 spinlock_t spinlock;
186 int is_locked;
187 wait_queue_head_t wait_queue;
188 struct timer_list timer;
189 struct tasklet_struct tasklet;
190 int timer_active;
191 int tasklet_active;
192 /* timer_active != 0 iff timer or irq is active */
193 int irq;
194 /* irq != 0 if board supports interrupts
195 = -irq if handler not installed
196 = irq if handler is installed */
197 volatile
198 int irq_count;
199 volatile
200 int i2c_bits;
201 /* last values written to i2c */
202 char saa7110_registers[HRT_SAA7110_MAXREG+1];
203 /* video data format, and dependent values */
204 int mode;
205 int rows, cols, bytes_per_pixel;
206 int win_row, win_col, win_width, win_height;
207 /* current field being digitized */
208 int field;
209 /* how many field changes we are waiting for */
210 int field_changes;
211 /* the device is either frozen or being frozen */
212 int is_frozen;
213
214 /* Local buffer for storing the frame currently read from the device */
215 /* Added june 8,2005 - atulya/sean */
216 unsigned char *framedata;
217 /* Variable to keep track of the field being read inside the current frame */
218 unsigned int field_id;
219 /* Semaphore for the device structure */
220 struct semaphore sem;
221 /* Local buffer used for manipulation of the data returned
222 * by the color device.
223 * ONLY used by the color device
224 */
225 unsigned char *localbuf;
226 /* Flag for streaming mode */
227 int streaming;
228 /* Number of buffers for streaming */
229 int numbufs;
230 /* Array of buffers */
231 struct stream_buffer *streambufs;
232 /* List of queued buffers */
233 struct stream_buffer_queue capture_list;
234 /* List of filled buffers */
235 struct stream_buffer_queue done_list;
236 int stream_buffers_mapped;
237 struct stream_buffer stream_buf[MAX_CAPTURE_BUFFERS];
238 int stream_buffers_requested;
239
240 /* Variable used to keep track of our state while streaming
241 * added 13 June 2005 - Atulya/Sean
242 */
243 int streaming_state;
244
245 /* We allow the user to make the view upside down too !
246 * came out of compulsion actually since we have the cameras installed
247 * upside down !
248 * the following variable determines what sort of output we return to the user
249 * set using an ioctl
250 */
251 int upside_down;
252
253 /* Following structure used for registering with V4L */
254 struct video_device video_dev;
255 struct v4l2_format clientfmt;
256 struct v4l2_captureparm capture;
257
258 /* Bytes per raster line. 640 for grey scale card
259 * and 2*640 = 1280 for the color card
260 */
261 unsigned int bytesperline;
262 /* Memory size of the entire frame
263 * = 512 X 480 X 1 bytes per pixel= 240 KB for grey scale card
264 * = 640 X 480 X 2 bytes per pixel= 600 KB for color card
265 */
266 unsigned int framesize;
267 /* Current region of interest
268 * fields = width,height,starty,startx
269 */
270 struct subwindow *win;
271
272 #ifdef CONFIG_PCI
273 /* structure to represent a pci device */
274 struct pci_dev *pci_dev;
275 #endif
276 } hrt_t;
277
278
279 /********************************************************************
280 *************** basic file operations (fops) ********************
281 */
282 int hrt_open (struct inode *inode, struct file *file);
283 int hrt_release(struct inode *inode, struct file *file);
284 int hrt_read (struct file *file, char *buf, size_t count, loff_t * ppos);
285 int hrt_ioctl (struct inode *inode, struct file *filp,
286 unsigned int cmd, unsigned long arg);
287 int hrt_mmap (struct file *file, struct vm_area_struct *vma);
288 unsigned int hrt_poll (struct file *file, poll_table *wait);
289 static int hrt_do_private_ioctl(hrt_t *hrtdev, unsigned int cmd,
290 unsigned long arg);
291
292
293 /********************************************************************/
294 static struct file_operations hrt_fops = {
295 .owner = THIS_MODULE,
296 .open = hrt_open,
297 .release = hrt_release,
298 .read = hrt_read,
299 .ioctl = hrt_ioctl,
300 .mmap = hrt_mmap,
301 .llseek = no_llseek,
302 .poll = hrt_poll,
303
304 };
305
306 /********************************************************************/
307 /* XXX: Get an actual official number from kraxel@bytesex.org
308 (see /usr/src/linux/include/linux/videodev.h) */
309 #define VID_HARDWARE_HRT 36
310
311 /********************************************************************/
312 static struct video_device videodev_template = {
313 .owner = THIS_MODULE,
314 .name = "HRT Pixelsmart (PS512-8-PCI)",
315 .type = HRT_VID_TYPE,
316 .hardware = VID_HARDWARE_HRT,
317 .fops = &hrt_fops,
318 };
319
320 /********************************************************************/
321 /**
322 * struct hrt_per_file - contains data to be stored per file handle
323 *
324 * Private data for a device is not just the hrt_t structure
325 * but also the subwindow structure that represents the subwindow
326 * of the entire frame being displayed
327 */
328 struct hrt_per_file {
329 struct subwindow win;
330 hrt_t *hrtdev;
331 };
332 /********************************************************************/
333
334 /* Minor number, or -1 for first free */
335 static int video_minor = -1;
336
337 /* Don't put V4L2_CAP_STREAMING in capabilities; recommended for xawtv */
338 static unsigned int disable_streaming = 0;
339
340 MODULE_PARM(video_minor, "i");
341 MODULE_PARM_DESC(video_minor, "Device's minor number (default: dynamic)");
342 MODULE_PARM(disable_streaming, "i");
343 MODULE_PARM_DESC(disable_streaming, "Don't return V4L2_CAP_STREAMING; recommended for xawtv (default: off)");
344
345 MODULE_AUTHOR("Brett W. Thompson, Gilberto Morejon, Veena Adityan, Arthi Gokarn, Alex Rudnick, Sean Toh, Atulya Mahajan");
346 MODULE_DESCRIPTION("Driver for HRT Pixelsmart 512-8-PCI");
347 MODULE_LICENSE("GPL");
348
349
350 /********************************************************************/
351 /**
352 * dprintk, hrt_printk - thin wrappers around printk()
353 */
354 #define dprintk(fmt, arg...) { printk("hrt: " fmt, ## arg); }
355 #define hrt_printk(fmt, arg...) { printk(KERN_ALERT "hrt: " fmt, ## arg); }
356 /********************************************************************/
357
358 /* values for field hrt_t->state */
359 #define HRT_UNINITIALIZED_STATE 1
360 #define HRT_INITIALIZING_STATE 2
361 #define HRT_CLOSED_STATE 4
362 #define HRT_OPEN_STATE 8
363 #define HRT_FINALIZING_STATE 16
364
365 /* values for field hrt_t->mode */
366 #define HRT_DUAL_PORTED_MODE 1
367 #define HRT_COLOR_MODE 2
368 #define HRT_STREAMING_MODE 4
369 #define HRT_IRQ_MODE 8
370 #define HRT_ISA_MODE 16
371
372 /* values for global hrt_module_state */
373
374 #define HRT_MODULE_UNINITIALIZED_STATE 1
375 #define HRT_MODULE_INITIALIZING_STATE 2
376 #define HRT_MODULE_INITIALIZED_STATE 4
377 #define HRT_MODULE_FINALIZING_STATE 8
378 /********************************************************************/
379
380
381 int hrt_module_state = HRT_MODULE_UNINITIALIZED_STATE;
382
383 int hrt_nonpci_devices = 0; /* number of non-pci devices detected */
384 /* non-pci devices have lower numbers */
385 int hrt_num_devices = 0; /* total number of devices detected */
386
387 #define HRT_IS_PCI(X) ((X) >= hrt_nonpci_devices)
388
389 /* ??? consider dynamically allocating the device
390 objects as they are probed and detected, and
391 using a linked list here instead of an array */
392
393 hrt_t hrt_devices[HRT_MAX_DEVICES];
394
395 /* Flag to change semantics of mmap() upon the IOC_HRT_NEXT_MMAP_IS_DIRECT
396 ioctl */
397 static unsigned int next_mmap_is_direct = 0;
398 struct hrt_per_file *per_file_init( hrt_t *hrtdev);
399
400
401 /* Veena and Arthi's streaming functions */
402 int mmap_request_buffers(hrt_t *dev,
403 struct v4l2_requestbuffers *req);
404 int hrt_streamon(hrt_t *hrtdev, __u32 type);
405 void hrt_streamoff(hrt_t *hrtdev, __u32 type);
406 int hrt_dequeuebuffer(hrt_t *hrtdev,
407 struct v4l2_buffer *buf);
408 int hrt_queuebuffer(hrt_t *hrtdev,
409 struct v4l2_buffer *buf);
410
411
412
413 #ifdef HRT_DEBUG
414 /******************************
415 * optional debugging support *
416 ******************************/
417
418 #define HRT_DEBUG_LEVEL 3
419
420 #define HRT_CHECK(dev,states,msg) \
421 {if (dev->state & ~(states))\
422 {HRT_DEBUG_MSG(1, "* unexpected state 0x%2x (%s)", dev->state, msg);}}
423
424 #define HRT_MODULE_CHECK(states,msg) \
425 {if (hrt_module_state & ~(states))\
426 {HRT_DEBUG_MSG(1, "* unexpected state 0x%2x (%s)", hrt_module_state, msg);}}
427
428 #define HRT_DEBUG_MSG(level,args...) {if (level <= HRT_DEBUG_LEVEL)\
429 {printk("<1>hrt * "); printk(args); printk("\n");}}
430
431 struct proc_dir_entry *hrt_proc_read_entry = NULL;
432
433 #define write_buf(args...) \
434 do { \
435 n = snprintf(buf, count, args); \
436 buf += n; \
437 count -= n; \
438 } while(0)
439
440 /********************************************************************/
441 int hrt_read_proc(char *buf, char **start, off_t offset,
442 int count, int *eof, void *data)
443 {
444 int n, i;
445 int ips, tps, rps;
446 char *org_buf = buf;
447
448 ips = 0;
449 tps = 0;
450 rps = 0;
451
452 /* dont excede count bytes when writing to buf */
453 /* just write to buf as a normal ptr to a file */
454
455 write_buf("dev HZ/10 int timer read int/s timer/s read/s\n");
456 for (i=0; i<HRT_MAX_DEVICES; i++) {
457 write_buf("%6i %6i %7i %9i %8i\n", i,
458 hrt_devices[i].irq_count,
459 ips, tps, rps);
460 }
461 *eof = 1;
462 return buf - org_buf;
463 }
464 /********************************************************************/
465
466 #define hrt_debug_init()\
467 { hrt_proc_read_entry = create_proc_read_entry("hrt0", 0, 0, hrt_read_proc, 0);}
468
469 #define hrt_debug_cleanup()\
470 {if (hrt_proc_read_entry) remove_proc_entry("hrt", 0);}
471
472 #else
473 /* hrt debugging is off */
474
475 #define HRT_CHECK(dev,states,msg) do{}while(0)
476 #define HRT_MODULE_CHECK(states,msg) do{}while(0)
477 #define HRT_DEBUG_MSG(args...) do{}while(0)
478 #define hrt_debug_init() do{}while(0)
479 #define hrt_debug_cleanup() do{}while(0)
480 #endif
481
482 /****************************
483 * low-level device control *
484 ****************************/
485
486 /* I2C bits */
487 #define HRT_I2C_SCL 0x01
488 #define HRT_I2C_SDA 0x02
489
490 #define HRT_CONTROL(addr) (addr + HRT_CONTROL_REG)
491 #define I2C_CONTROL(addr) (addr + HRT_I2C_REG)
492 #define I2C_BUSY(addr) (!(ioread8((void *) HRT_CONTROL(addr)) & 0x80))
493
494 /* Bit 7 at 0x2000 (the HRT512-8 control register) tells whether
495 * the CPU is sending data across the I2C bus */
496
497 #define hrt_freeze_next(dev) \
498 dev->is_frozen = 1;\
499 iowrite8(HRT_FREEZE_NEXT_CMD, (void *) (dev->virt_addr + HRT_CONTROL_REG))
500 #define hrt_freeze_immediate(dev) \
501 dev->is_frozen = 1;\
502 iowrite8(HRT_FREEZE_IMM_CMD, (void *) (dev->virt_addr + HRT_CONTROL_REG))
503 #define hrt_go_live(dev) \
504 dev->is_frozen = 0;\
505 iowrite8(HRT_LIVE_CMD, (void *) (dev->virt_addr + HRT_CONTROL_REG))
506 #define hrt_get_field(dev) \
507 ioread8((void *) (dev->virt_addr + HRT_CONTROL_REG)) & 0x1
508 #define hrt_is_live(dev) \
509 ioread8((void *) (dev->virt_addr + HRT_CONTROL_REG)) & 0x1
510 #define hrt_i2c_delay() udelay(5)
511
512 /* Unique I2C bus address of the SAA7110 (A/D) device */
513 #define HRT_AD_DEVICE_ID (128+16+8+4)
514
515 /********************************************************************/
516 const unsigned char saa7110_default_init_regs[] = {
517 94, /* there are 94 bytes that follow */
518 0x00, 0x4c, /* increment delay (IDEL) */
519 0x01, 0x3c, /* HSY begin 50 Hz */
520 0x02, 0x0d, /* HSY stop 50 Hz */
521 0x03, 0xef, /* HCL begin 50 Hz */
522 0x04, 0xbd, /* HCL stop 50 Hz */
523 0x05, 0xf0, /* HSY after PHI1 50 Hz */
524 0x06, 0x00, /* luminance control */
525 0x07, 0x00, /* hue control */
526 0x08, 0xf8, /* colour killer threshold QUAM (PAL/NTSC) */
527 0x09, 0xf8, /* colour killer threshold SECAM */
528 0x0A, 0x60, /* PAL switch sensitivity */
529 0x0B, 0x50, /* SECAM switch sensitivity */
530 0x0C, 0x00, /* gain control chrominance */
531 0x0D, 0x86, /* standard/mode control */
532 /* 7 VTRC = 1 (VCR mode, not TV)
533 6 XXX
534 5 XXX
535 4 XXX
536 3 RTSE = 0 (PLIN switched to output)
537 2 HRMV = 1 (HREF normal position)
538 1 SSTB = 1 (status byte = 1)
539 0 SECS = 0 (other standards, not SECAM) */
540 0x0E, 0x18, /* I/O and clock control */
541 0x0F, 0x90, /* control #1 */
542 0x10, 0x00, /* control #2 */
543 0x11, 0x2c, /* chrominance gain reference */
544 0x12, 0x7f, /* chrominance saturation */
545 0x13, 0x5e, /* luminance contrast */
546 0x14, 0x42, /* HSY begin 60 Hz */
547 0x15, 0x1a, /* HSY stop 60 Hz */
548 0x16, 0xff, /* HCL begin 60 Hz */
549 0x17, 0xda, /* HCL stop 60 Hz */
550 0x18, 0xf0, /* HSY after PHI1 60 Hz */
551 0x19, 0x9b, /* luminance brightness */
552 /*
553 0x1A - not used
554 0x1B - not used
555 0x1C - not used
556 0x1D - not used
557 0x1E - not used
558 0x1F - not used
559 */
560 0x20, 0x7c, /* analog control #1 */
561 0x21, 0x03, /* analog control #2 */
562 0x22, 0xd2, /* mixer control #1 */
563 0x23, 0x41, /* clamping level control 21 */
564 0x24, 0x80, /* clamping level control 22 */
565 0x25, 0x41, /* clamping level control 31 */
566 0x26, 0x80, /* clamping level control 32 */
567 0x27, 0x4f, /* gain control #1 */
568 0x28, 0xfe, /* white peak control */
569 0x29, 0x01, /* sync bottom control */
570 0x2A, 0xcf, /* gain control analog #2 */
571 0x2B, 0x0f, /* gain control analog #3 */
572 0x2C, 0x83, /* mixer control #2 */
573 0x2D, 0x01, /* integration value gain */
574 0x2E, 0x81, /* vertical blanking pulse set */
575 0x2F, 0x03, /* vertical blanking pulse reset */
576 0x30, 0x60, /* ADCs gain control */
577 0x31, 0x71, /* mixer control #3 */
578 0x32, 0x02, /* integration value white peak */
579 0x33, 0x8c, /* mixer control #4 */
580 0x34, 0x03, /* gain update level */
581 };
582
583 /********************************************************************/
584 /*
585 * sda = set data bit on I2C bus
586 * to the value given by parameter high
587 */
588 static inline
589 void hrt_sda(hrt_t *dev, unsigned long addr, int high)
590 {
591 if (high) dev->i2c_bits |= HRT_I2C_SDA;
592 else dev->i2c_bits &= ~HRT_I2C_SDA;
593 iowrite8(dev->i2c_bits, (void *) I2C_CONTROL(addr));
594 wmb();
595 }
596
597 /********************************************************************/
598 /*
599 * scl = set clock bit on I2C bus
600 * to the value given by parameter high
601 */
602 static inline
603 void hrt_scl(hrt_t *dev, unsigned long addr, int high)
604 {
605 if (high) dev->i2c_bits |= HRT_I2C_SCL;
606 else dev->i2c_bits &= ~HRT_I2C_SCL;
607 iowrite8(dev->i2c_bits, (void *) I2C_CONTROL(addr));
608 wmb();
609 }
610
611 /********************************************************************/
612 /**
613 * Queue manipulation functions (basically wrappers for the Linux
614 * linked list functions)
615 */
616 void queue_add_tail(struct stream_buffer *streambuf,
617 struct stream_buffer_queue *q)
618 {
619 unsigned long flags;
620
621 if (streambuf == NULL || q == NULL) return;
622
623 write_lock_irqsave(&q->lock, flags);
624 list_add_tail(&streambuf->node, &q->head);
625 q->length++;
626 write_unlock_irqrestore(&q->lock, flags);
627 }
628
629 /********************************************************************/
630 void queue_del(struct stream_buffer *streambuf,
631 struct stream_buffer_queue *q)
632 {
633 unsigned long flags;
634
635 if (q == NULL) return;
636
637 write_lock_irqsave(&q->lock, flags);
638 list_del(&streambuf->node);
639 q->length--;
640 write_unlock_irqrestore(&q->lock, flags);
641 }
642
643 /********************************************************************/
644 struct stream_buffer *queue_peek_head(struct stream_buffer_queue *q)
645 {
646 unsigned long flags;
647 struct stream_buffer *streambuf;
648
649 if (q == NULL) return NULL;
650
651 read_lock_irqsave(&q->lock, flags);
652 streambuf = list_entry(q->head.next, struct stream_buffer, node);
653 read_unlock_irqrestore(&q->lock, flags);
654
655 return streambuf;
656 }
657
658 /********************************************************************/
659 struct stream_buffer *queue_del_head(struct stream_buffer_queue *q)
660 {
661 unsigned long flags;
662 struct stream_buffer *streambuf;
663
664 if (q == NULL) return NULL;
665 if (!q->length) return NULL;
666
667 read_lock_irqsave(&q->lock, flags);
668 streambuf = list_entry(q->head.next, struct stream_buffer, node);
669 list_del(&streambuf->node);
670 q->length--;
671 read_unlock_irqrestore(&q->lock, flags);
672 return streambuf;
673 }
674
675 /********************************************************************/
676 /**
677 * hrt_streamoff - called by the STREAMOFF ioctl.
678 * Used to turn off the streaming read from the device
679 */
680 void hrt_streamoff(hrt_t *hrtdev, __u32 type)
681 {
682 int i = 0;
683 struct stream_buffer *buf;
684 /* Cant turn streaming off if it isnt on !! */
685 if (!hrtdev->streaming) {
686 hrt_printk("STREAMOFF - Not in streaming mode\n");
687 return;
688 }
689 /* We can only have the following type specified
690 * anything else is an error
691 */
692 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
693 hrt_printk("STREAMOFF - Wrong buffer type\n");
694 return;
695 }
696 /* Set the 'streaming' variable to 0
697 * indicates that we are no more in streaming mode
698 * used by the timer handler to determine what to do
699 */
700 hrtdev->streaming = 0;
701
702 /* Added 13 June 2005 - Atulya/Sean */
703 hrtdev->streaming_state = 0;
704
705 hrtdev->upside_down = 0;
706
707 /* Wait till the queue is empty */
708 while ((buf = queue_del_head(&hrtdev->done_list))) {
709 buf->vidbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
710 i++;
711 }
712
713 hrt_printk("Streaming is turned off\n");
714 }
715
716
717
718 /********************************************************************/
719 /**
720 * hrt_do_private_ioctl - handle private ioctl's on device
721 */
722 static int hrt_do_private_ioctl(hrt_t *hrtdev, unsigned int cmd,
723 unsigned long arg)
724 {
725 if (cmd == IOC_HRT_NEXT_MMAP_IS_DIRECT) {
726 /* The next mmap() that's called on /dev/video<n>
727 will map the device's memory directly- this is
728 for userspace drivers */
729 next_mmap_is_direct = 1;
730 return 0;
731 }
732 /*else if (cmd == IOC_HRT_SET_I2CREG) {
733 struct i2c_regval r;
734
735 if (copy_from_user(&r, (void *) arg, sizeof(r))) {
736 return -EFAULT;
737 }
738 i2c_set_reg(hrtdev, r.reg, r.val);
739 return 0;
740 } else if (cmd == IOC_HRT_GET_I2CREG) {
741 struct i2c_regval r;
742
743 r.val = hrtdev->regvals[r.reg];
744 if (copy_to_user((void *) arg, &r, sizeof(r))) {
745 return -EFAULT;
746 }
747 return 0;
748 }
749 */
750 /* Set the region of interest - subwindow */
751 else if (cmd == IOC_HRT_SET_ROI) {
752 struct subwindow win;
753
754 if (copy_from_user(&win, (void *) arg, sizeof(win))) {
755 hrt_printk("ioctl IOC_HRT_SET_ROI failed\n");
756 return -EFAULT;
757 }
758 /* Check if the specified height and width are valid values */
759 if (win.height > HRT_HEIGHT || win.height < 0) return -EINVAL;
760 if(hrtdev->mode & HRT_COLOR_MODE){
761 if (win.width > HRT_COLOR_WIDTH || win.width < 0) return -EINVAL;
762 }
763 else{
764 if (win.width > HRT_GRAY_WIDTH || win.width < 0) return -EINVAL;
765 }
766 if (win.startx > win.width || win.startx < 0) return -EINVAL;
767 if (win.starty > win.height || win.starty < 0) return -EINVAL;
768 hrt_printk ("setting hrtdev->win\n");
769 *hrtdev->win = win;
770 return 0;
771 /* Return the current region of interest parameters to the user */
772 } else if (cmd == IOC_HRT_GET_ROI) {
773 if (copy_to_user((void *) arg, hrtdev->win,
774 sizeof(*hrtdev->win))) {
775 hrt_printk("ioctl IOC_HRT_GET_ROI failed\n");
776 return -EFAULT;
777 }
778 return 0;
779 }
780 /* else if (cmd == IOC_HRT_SET_I2CREGS) { */
781 /* unsigned char len; */
782 /* int retval; */
783 /* unsigned char *buf; */
784
785 /* /\* Stop the timer first *\/ */
786 /* del_timer_sync(&timer); */
787 /* timer_running = 0; */
788
789 /* /\* First byte is the length of the array *\/ */
790 /* if (copy_from_user(&len, (void *) arg, 1)) */
791 /* return -EFAULT; */
792 /* dprintk("size of array = %d\n", len); */
793
794 /* buf = vmalloc(len + 1); */
795 /* if (copy_from_user(buf, (void *) arg, len)) { */
796 /* vfree(buf); */
797 /* return -EFAULT; */
798 /* } */
799 /* retval = i2c_init(hrtdev, buf); */
800 /* vfree(buf); */
801
802 /* /\* Start the timer again *\/ */
803 /* timer.expires = jiffies + (HZ/100); */
804 /* add_timer(&timer); */
805 /* timer_running = 1; */
806 /* return retval; */
807
808 return -EINVAL;
809 }
810
811
812 /********************************************************************/
813 /**
814 * hrt_direct_mmap - provides direct access to the card's memory
815 */
816 static int hrt_direct_mmap(struct file *file, struct vm_area_struct *vma)
817 {
818 struct hrt_per_file *per_file = file->private_data;
819 hrt_t *hrtdev = per_file->hrtdev;
820 vma->vm_flags |= (VM_IO | VM_RESERVED);
821 /* Just map the pages directly */
822 if (remap_pfn_range(vma,
823 vma->vm_start, hrtdev->phys_addr, vma->vm_end - vma->vm_start,
824 vma->vm_page_prot))
825 return -EAGAIN;
826
827 return 0;
828 }
829
830
831 /********************************************************************/
832 /**
833 * mmap_stream_buffer_from_offset - get a buffer via the specified offset
834 */
835 static struct stream_buffer *mmap_stream_buffer_from_offset(hrt_t *dev,
836 unsigned long offset)
837 {
838 int i;
839 offset *= PAGE_SIZE;
840 for (i = 0; i < MAX_CAPTURE_BUFFERS; ++i) {
841 if (offset == dev->stream_buf[i].vidbuf.m.offset) {
842 hrt_printk("mmap_stream_buffer_from_offset: offset found at : 0x%lx", offset);
843 return &dev->stream_buf[i];
844 }
845 }
846 hrt_printk("mmap_stream_buffer_from_offset: NOTHING found.");
847 return NULL;
848 }
849
850 /*
851 *
852 * Dr Baker's I2C routines follow
853 *
854 */
855
856 /********************************************************************/
857 /*
858 * sda_scl = set data and clock bits on I2C bus
859 * to the values given by parameters sda_high and scl_high
860 */
861 static inline
862 void hrt_sda_scl(hrt_t *dev,
863 unsigned long addr, int sda_high, int scl_high)
864 {
865 if (sda_high) dev->i2c_bits |= HRT_I2C_SDA;
866 else dev->i2c_bits &= ~HRT_I2C_SDA;
867 if (scl_high) dev->i2c_bits |= HRT_I2C_SCL;
868 else dev->i2c_bits &= ~HRT_I2C_SCL;
869 iowrite8(dev->i2c_bits, (void *) I2C_CONTROL(addr));
870 wmb();
871 }
872
873 /********************************************************************/
874 /*
875 * sda_read = read data bit from I2C control register
876 */
877 static inline
878 int hrt_sda_read(unsigned long addr)
879 { char c = ioread8((void *) I2C_CONTROL(addr)); return (c & HRT_I2C_SDA); }
880
881
882 /********************************************************************/
883 /*
884 * hrt_i2c_start = start I2C data transmission
885 */
886 static inline
887 void hrt_i2c_start(hrt_t *dev, unsigned long addr)
888 {
889 hrt_sda_scl(dev, addr, 0, 0);
890 hrt_i2c_delay();
891 hrt_sda(dev, addr, 1);
892 hrt_i2c_delay();
893 hrt_scl(dev, addr, 1);
894 hrt_i2c_delay();
895 hrt_sda(dev, addr, 0);
896 hrt_i2c_delay();
897 hrt_scl(dev, addr, 0);
898 }
899
900 /********************************************************************/
901 /*
902 * hrt_i2c_stop = end I2C data transmission
903 */
904 static inline
905 void hrt_i2c_stop(hrt_t *dev, unsigned long addr)
906 {
907 hrt_sda_scl(dev, addr, 0, 0);
908 hrt_i2c_delay();
909 hrt_scl(dev, addr, 1);
910 hrt_i2c_delay();
911 hrt_sda(dev, addr, 1);
912 hrt_i2c_delay();
913 hrt_scl(dev, addr, 0);
914 hrt_scl(dev, addr, 1);
915 }
916
917 /********************************************************************/
918 /*
919 * hrt_i2c_send_bit
920 */
921 static
922 int hrt_i2c_send_bit(hrt_t *dev,
923 unsigned long addr, unsigned char bit)
924 {
925 unsigned long timeout;
926 if (bit) hrt_sda(dev, addr, 1);
927 else hrt_sda(dev, addr, 0);
928 hrt_i2c_delay();
929 iowrite8(dev->i2c_bits | 0x04, (void *) I2C_CONTROL(addr));
930 wmb();
931 hrt_i2c_delay();
932 if (I2C_BUSY(addr)) {
933 timeout = jiffies + HZ/10;
934 while (I2C_BUSY(addr)) {
935 if (jiffies > timeout) {
936 HRT_ERROR_MSG("i2c bus timeout");
937 return -1;
938 }
939 }
940 }
941 return 0;
942 }
943
944 /********************************************************************/
945 /*
946 * hrt_i2c_send_byte
947 */
948 static
949 int hrt_i2c_send_byte(hrt_t *dev, unsigned long addr, unsigned char data)
950 {
951 char bitpos, bit;
952 for(bitpos = 0; bitpos < 8; bitpos++) {
953 bit = (data & 0x80) >> 7;
954 data <<= 1;
955 if(hrt_i2c_send_bit(dev, addr, bit)) goto failure;
956 }
957 hrt_i2c_delay();
958 hrt_sda_scl(dev, addr, 1, 0);
959 hrt_scl(dev, addr, 1); /* leave clock high */
960 udelay(10);
961 if (hrt_sda_read(addr)) {
962 HRT_ERROR_MSG("no i2c ack");
963 goto failure;
964 }
965 hrt_sda_scl(dev, addr, 1, 0);
966 return 0;
967 failure:
968 hrt_sda_scl(dev, addr, 1, 0);
969 hrt_i2c_stop(dev, addr);
970 return -1;
971 }
972
973 /********************************************************************/
974 /*
975 * hrt_i2c_init_registers
976 *
977 * sends a sequence of values to the A/D converter device over the I2C bus.
978 * For an example of the format of "sequence" see the declaration of
979 * saa7110_default_init_regs[] above. The first byte is the number of
980 * data bytes that follow. The rest of the sequence is a series of pairs
981 * of a register number followed by a value. It is better if the values
982 * are sorted in increasing order of register number, but the sequence may
983 * have gaps and need not be in order.
984 */
985 int hrt_i2c_init_registers(hrt_t *dev, const char *sequence)
986 {
987 unsigned long addr;
988 int i, len, cur_reg;
989
990 len = (int) (*sequence++);
991 addr = dev->virt_addr;
992
993 if (len <= 2) {
994 HRT_ERROR_MSG("invalid register initialization sequence");
995 return -1;
996 }
997
998 hrt_i2c_start(dev, addr);
999
1000 /* here we select the A/D Device on the i2c bus
1001 * that should pay attention to the following bytes */
1002 if (hrt_i2c_send_byte(dev, dev->virt_addr, HRT_AD_DEVICE_ID)) {
1003 HRT_ERROR_MSG("send_byte failed");
1004 return -1;
1005 }
1006
1007 /* start at the first register and increment along the way */
1008 if (hrt_i2c_send_byte(dev, dev->virt_addr, cur_reg = sequence[0])) {
1009 HRT_ERROR_MSG("send_byte failed(2)");
1010 return -1;
1011 }
1012
1013 for(i = 0; i < len; i += 2, sequence += 2) {
1014 char reg = sequence[0];
1015 char data = sequence[1];
1016 if (reg > HRT_SAA7110_MAXREG) {
1017 HRT_ERROR_MSG("register %02X out of range!", reg);
1018 return -1;
1019 }
1020 if (reg != cur_reg) {
1021
1022 /* we're going to an entirely different register */
1023 hrt_i2c_stop(dev, addr);
1024 hrt_i2c_start(dev, addr);
1025
1026 /* select the chip/device on the bus */
1027 if (hrt_i2c_send_byte(dev, dev->virt_addr, HRT_AD_DEVICE_ID)) {
1028 HRT_ERROR_MSG("send_byte failed(3)");
1029 return -1;
1030 }
1031
1032 /* select the register */
1033 if (hrt_i2c_send_byte(dev, dev->virt_addr, cur_reg = reg)) {
1034 HRT_ERROR_MSG("send_byte failed(4)");
1035 return -1;
1036 }
1037 }
1038
1039 if (hrt_i2c_send_byte(dev, dev->virt_addr, data)) {
1040 HRT_ERROR_MSG("send_byte failed(5)");
1041 return -1;
1042 }
1043 dev->saa7110_registers[cur_reg++] = data;
1044 }
1045 /* free the i2c bus */
1046 hrt_i2c_stop(dev, addr);
1047 return 0;
1048 }
1049
1050 /********************************************************************/
1051 int hrt_i2c_init_device(hrt_t *dev)
1052 {
1053 int result = 0;
1054 HRT_DEBUG_MSG(2, "hrt_i2c_init_device entered"
1055 " (virt_addr = %08X, addr = %08X)",
1056 (unsigned) dev->virt_addr,
1057 (unsigned) dev->phys_addr);
1058
1059 result = hrt_i2c_init_registers(dev, saa7110_default_init_regs);
1060 if (result) {
1061 HRT_ERROR_MSG("hrt_i2c_init_registers failed %d", result);
1062 return result;
1063 }
1064 HRT_DEBUG_MSG(2, "hrt_i2c_init_device returning %d", result);
1065 return result;
1066 }
1067
1068
1069 /********************************************************************
1070 *
1071 * grab_field
1072 *
1073 * Function that reads one field from the device and copies it to the
1074 * hrtdev->framedata buffer. This grab_field is executed twice to read
1075 * fields and then we have a complete frame for the user.
1076
1077 * This function is implemented differantly for color and gray scale devices
1078 * since they are stored differantly inside the device's memory
1079 * the grey scale implementation is straightforward
1080 * but the color device stores its data in a peculiar fashion.
1081 * Each line has 1664 bytes organised as follows
1082 * 512 bytes - first 512 LSBs
1083 * 512 bytes - first 512 MSBs
1084 * 128 bytes - last 128 LSBs
1085 * 384 bytes - BLANK !!
1086 * 128 bytes - last 128 MSBs
1087 * All this needs to be reorganised the 1280 bytes for one line
1088 * And in case of a smaller subwindow the coordinates of the subwindow
1089 * need to be taken care of while implementing this
1090 *
1091 * the 'parity' argument determines the location of this field
1092 * inside the current frame
1093 *
1094 * Point to note -
1095 * GreyScale requires 1 byte per pixel
1096 * Color requires 2 bytes per pixel
1097 */
1098 void grab_field( hrt_t *hrtdev, unsigned char *framedata,
1099 int parity)
1100 {
1101 int i,j,k;
1102 /* Length of the line; used here only by the grey scale implementation */
1103 int linelen;
1104 /* Coordinates of the sub window */
1105 int win_width, win_height, win_col, win_row;
1106 win_width = hrtdev->win->width;
1107 win_height = hrtdev->win->height;
1108 win_row = hrtdev->win->starty;
1109 win_col = hrtdev->win->startx;
1110
1111 if( (hrtdev->mode & HRT_COLOR_MODE) ){
1112 linelen = hrtdev->win->width;
1113 /* For the color case we split up work into three cases
1114 * Case 1 : window completely to the left of the 512 pixel boundary
1115 * Case 2 : window crossing the 512 pixel boundary
1116 * Case 3 : window completely to the right of the 512 pixel boundary
1117 last 128 pixels of the row
1118 */
1119
1120 for (i = (!parity) + win_row; i < win_height; i += 2) {
1121 /* Write the address of the required line into the register */
1122 iowrite16(i, (void*)hrtdev->virt_addr + HRT_Y_LOW_REG);
1123 wmb();
1124 /* color card - number of bytes required = 2 X win_width */
1125 memset(hrtdev->localbuf, 0, 2*win_width);
1126
1127 /* Case 1 */
1128 if ( (win_col + win_width) < 512){
1129 /* Get the first win_width MSBs */
1130 memcpy(hrtdev->localbuf, (void *)hrtdev->virt_addr + win_col, win_width);
1131 /* Get the first win_width LSBs */
1132 memcpy(hrtdev->localbuf + win_width, (void *)hrtdev->virt_addr + 512 + win_col, win_width);
1133 }
1134
1135 /* Case 2
1136 * This one gets messy, but this is correct
1137 * and works fine !
1138 * all this for efficiency !
1139 * */
1140 else if ( ((win_col +win_width) >= 512) && (win_col < 512) ){
1141 /* Get the first (512 - win_col) MSBs */
1142 memcpy(hrtdev->localbuf, (void *)hrtdev->virt_addr + win_col ,
1143 512 - win_col);
1144 /* Get the last (win_width - 512 + win_col) MSBs */
1145 memcpy(hrtdev->localbuf+ 512 - win_col, (void *)hrtdev->virt_addr + 1024,
1146 win_width -512 +win_col);
1147 /* Get the first (512 - win_col) LSBs */
1148 memcpy(hrtdev->localbuf + win_width , (void *)hrtdev->virt_addr + 512 + win_col,
1149 512 - win_col);
1150 /* Get the last (win_width - 512 + win_col) LSBs */
1151 memcpy(hrtdev->localbuf + win_width +512 - win_col, (void *)hrtdev->virt_addr + 1536,
1152 win_width - 512 + win_col);
1153 }
1154
1155 /* Case 3 */
1156 else if ( ((win_col +win_width) >= 512) && (win_col >= 512) ){
1157 /* Get the first win_width MSBs */
1158 memcpy(hrtdev->localbuf, (void *)hrtdev->virt_addr + win_col + 1024, win_width);
1159 /* Get the first win_width MSBs */
1160 memcpy(hrtdev->localbuf + win_width, (void *)hrtdev->virt_addr + 1536 + win_col, win_width);
1161 }
1162 /* At this point for all three cases we have all the bytes
1163 * stored in the form of all MSBs followed by all LSBs
1164 * Now copy into the framedata buffer one MSB followed
1165 * by the corresponding LSB
1166 *
1167 * However the destination for the copy is differant for the case of streaming I/O
1168 * as compared to the regular reads.
1169 * For streaming, we want to copy into the buffer that was passed as a parameter to
1170 * this function
1171 * But for the read operation we need to copy into the device's frame sized buffer 'framedata'
1172 *
1173 * Neat !!!
1174 *
1175 */
1176 if (!hrtdev->streaming) {
1177 /* This is for the blocking read based display */
1178 for (k = 0; k < win_width; k++) {
1179 j = k;
1180 if ( !(hrtdev->upside_down) ){
1181 hrtdev->framedata[(i*2*win_width) + 2*k] = hrtdev->localbuf[j];
1182 hrtdev->framedata[(i*2*win_width) + 2*k+1] = hrtdev->localbuf[j+win_width];
1183 }
1184 else {
1185 /* If the user wishes to see the image upside down then this code
1186 * makes that happen. In our case we as user wanted to have that functionality
1187 * since our camera was mounted upside down. So implemented this feature !!
1188 */
1189 hrtdev->framedata[((win_height-i+win_row-parity)*2*win_width) + 2*k] = hrtdev->localbuf[j];
1190 hrtdev->framedata[((win_height-i+win_row-parity)*2*win_width) + 2*k+1] = hrtdev->localbuf[j+win_width];
1191 }
1192 }
1193 }
1194 else {
1195 /* This is for the streaming I/O */
1196 for (k = 0; k < win_width; k++) {
1197 j = k;
1198 if ( !(hrtdev->upside_down) ){
1199 framedata[(i*2*win_width) + 2*k] = hrtdev->localbuf[j];
1200 framedata[(i*2*win_width) + 2*k+1] = hrtdev->localbuf[j+win_width];
1201 }
1202 else {
1203 /* If the user wishes to see the image upside down then this code
1204 * makes that happen. In our case we as user wanted to have that functionality
1205 * since our camera was mounted upside down. So implemented this feature !!
1206 */
1207 framedata[((win_height-i+win_row-parity)*2*win_width) + 2*k] = hrtdev->localbuf[j];
1208 framedata[((win_height-i+win_row-parity)*2*win_width) + 2*k+1] = hrtdev->localbuf[j+win_width];
1209 }
1210 }
1211 }
1212 }
1213 }
1214 else { /* Out of the color mode. This one is for gray scale */
1215 /* Following takes care of the sub window coordinates */
1216 linelen = hrtdev->win->width - hrtdev->win->startx;
1217 /* Since this is just a single field that we are writing into the buffer
1218 * we write each line of this field into an alternate line of the buffer.
1219 * Interleaving.
1220 */
1221 if (hrtdev->upside_down == 1) {
1222
1223 for (i = (!parity) + hrtdev->win->starty; i < hrtdev->win->height; i += 2) {
1224 iowrite16(i, (void *)hrtdev->virt_addr + HRT_Y_LOW_REG);
1225 wmb();
1226 /* Copy into the 'framedata' the desired part of the current line,
1227 * at the correct location inside the buffer
1228 */
1229 memcpy_fromio(framedata + (hrtdev->win->height - i - parity - hrtdev->win->starty) * linelen,
1230 (void *)hrtdev->virt_addr + hrtdev->win->starty,
1231 linelen);
1232 }
1233 }
1234 else {
1235 for (i = (!parity) + hrtdev->win->starty; i < hrtdev->win->height; i += 2) {
1236 iowrite16(i, (void *)hrtdev->virt_addr + HRT_Y_LOW_REG);
1237 wmb();
1238 /* Copy into the 'framedata' the desired part of the current line,
1239 * at the correct location inside the buffer
1240 */
1241 memcpy_fromio(framedata + (i * linelen),
1242 (void *)hrtdev->virt_addr + hrtdev->win->starty,
1243 linelen);
1244
1245 }
1246 }
1247
1248 }
1249
1250 }
1251
1252 /********************************************************************/
1253 static inline
1254 void hrt_irq_enable(hrt_t *dev)
1255 {
1256 int val;
1257 val = ioread8((void *)(dev->virt_addr + HRT_IRQ_ENABLE));
1258 val |= 0x1;
1259 iowrite8(val, (void *) (dev->virt_addr + HRT_IRQ_ENABLE));
1260 }
1261
1262 /********************************************************************/
1263 static inline
1264 void hrt_irq_disable(hrt_t *dev)
1265 {
1266 int val;
1267 val = ioread8((void *)(dev->virt_addr + HRT_IRQ_ENABLE));
1268 val &= ~0x1;
1269 iowrite8(val, (void *) (dev->virt_addr + HRT_IRQ_ENABLE));
1270 }
1271
1272 /********************************************************************
1273 ******** timer/tasklet related functions declared here ***********
1274 */
1275
1276 void hrt_tasklet(unsigned long);
1277 void hrt_timer_init(hrt_t* dev);
1278 void hrt_timer_cleanup(hrt_t* dev);
1279 int hrt_timer_activate(hrt_t* dev);
1280 void hrt_timer_deactivate(hrt_t* dev);
1281
1282
1283 /********************************************************************
1284 * hrt_cleanup
1285 *
1286 * Cleanup the device - called from the module cleanup routine
1287 */
1288
1289 void hrt_cleanup(hrt_t* dev)
1290 {
1291 HRT_DEBUG_MSG(1, "shutting down hrt device %d at 0x%lx",
1292 dev->num, dev->phys_addr);
1293 HRT_MODULE_CHECK (HRT_MODULE_FINALIZING_STATE |
1294 HRT_MODULE_INITIALIZING_STATE, "1");
1295 HRT_CHECK (dev, HRT_INITIALIZING_STATE
1296 | HRT_CLOSED_STATE | HRT_FINALIZING_STATE, "2");
1297 dev->state = HRT_FINALIZING_STATE;
1298
1299 /* restore device to an inactive state */
1300 hrt_freeze_next(dev);
1301
1302 /* deactivate and remove interrupt handler or timer */
1303 hrt_timer_cleanup (dev);
1304
1305 if (dev->phys_addr) {
1306 HRT_DEBUG_MSG(2, "release_mem_region 0x%lx, 0x%lx",
1307 (unsigned long)dev, (unsigned long) dev->phys_addr);
1308 release_mem_region(dev->phys_addr, HRT_IO_SIZE);
1309 dev->phys_addr = 0;
1310 }
1311 if (dev->virt_addr) {
1312 HRT_DEBUG_MSG(2, "iounmap %lx", (unsigned long) dev->virt_addr);
1313 iounmap((void *)dev->virt_addr);
1314 dev->virt_addr = 0;
1315 }
1316 #ifdef CONFIG_PCI
1317 if (dev->pci_dev) {
1318 pci_disable_device(dev->pci_dev);
1319 dev->pci_dev = NULL;
1320 }
1321 #endif
1322
1323 /* De-allocate frame buffer */
1324 if (dev->framedata) {
1325 vfree(dev->framedata);
1326 dev->framedata = NULL;
1327 }
1328 /* Deallocate the smaller local buffer */
1329 if (dev->localbuf) {
1330 kfree(dev->localbuf);
1331 dev->localbuf = NULL;
1332 }
1333
1334 /* Set the device state to uninitialised
1335 * now that it is all cleaned up
1336 */
1337 dev->state = HRT_UNINITIALIZED_STATE;
1338
1339 }
1340
1341 /********************************************************************
1342 * hrt_lock_init
1343 *
1344 * Initialises the spin lock used in the module
1345 */
1346 void hrt_lock_init(hrt_t * dev) {
1347 spin_lock_init(&dev->spinlock);
1348 dev->is_locked = 0;
1349 }
1350
1351 /********************************************************************
1352 * hrt_trylock
1353 *
1354 * Does nothing. Just checks the spinlock.
1355 */
1356 int hrt_trylock(hrt_t * dev) {
1357 spin_lock(&dev->spinlock);
1358 if (dev->is_locked) {
1359 spin_unlock(&dev->spinlock);
1360 return 1;
1361 }
1362 dev->is_locked = 1;
1363 spin_unlock(&dev->spinlock);
1364 return 0;
1365 }
1366
1367 /********************************************************************
1368 * hrt_lock
1369 *
1370 * lock the device
1371 */
1372 void hrt_lock(hrt_t * dev) {
1373 unsigned long flags;
1374 spin_lock_irqsave(&dev->spinlock, flags);
1375 if (dev->is_locked) {
1376 HRT_ERROR_MSG("locking an already-locked device");
1377 }
1378 dev->is_locked = 1;
1379 spin_unlock_irqrestore(&dev->spinlock, flags);
1380 }
1381
1382 /********************************************************************
1383 * hrt_unlock
1384 *
1385 * Unlock the device
1386 */
1387 void hrt_unlock(hrt_t * dev) {
1388 spin_lock(&dev->spinlock);
1389 if (!dev->is_locked) {
1390 HRT_ERROR_MSG("unlocking unlocked device");
1391 }
1392 dev->is_locked = 0;
1393 spin_unlock(&dev->spinlock);
1394 }
1395
1396 /********************************************************************
1397 * hrt_init
1398 *
1399 * Long function..
1400 * Probes and initialises the device
1401 */
1402 int hrt_init(unsigned long phys_address, struct pci_dev * pci_dev)
1403 {
1404 hrt_t * dev = &hrt_devices[hrt_num_devices];
1405 int i, result;
1406 char *bus, *color, *ported;
1407 unsigned int old_control, old_y_high, old_y_low;
1408 unsigned char val1, val2;
1409 unsigned long virt_address;
1410
1411 HRT_DEBUG_MSG(1, "probing device at 0x%lx", phys_address);
1412
1413 memset(dev, 0, sizeof(hrt_t));
1414
1415 dev = &hrt_devices[hrt_num_devices];
1416
1417 dev->state = HRT_INITIALIZING_STATE;
1418 dev->num = hrt_num_devices;
1419 hrt_lock_init (dev);
1420
1421 tasklet_init(&dev->tasklet, hrt_tasklet, (unsigned long) dev);
1422 dev->tasklet_active = 1;
1423
1424 /* reserve the I/O address space for this device */
1425 if (!request_mem_region(phys_address, HRT_IO_SIZE, "hrt")) {
1426 HRT_ERROR_MSG("I/O memory at %lx already in use",
1427 (unsigned long) phys_address);
1428 // hrt_cleanup(dev);
1429 return -EBUSY;
1430 }
1431 dev->phys_addr = phys_address;
1432
1433 /* map the device's I/O space into kernel memory */
1434 virt_address = (unsigned long)
1435 ioremap_nocache(phys_address, HRT_IO_SIZE);
1436 if (!virt_address) {
1437 HRT_ERROR_MSG("couldn't remap io memory!!");
1438 hrt_cleanup(dev);
1439 return -ENODEV;
1440 }
1441 dev->virt_addr = virt_address;
1442
1443 #ifdef CONFIG_PCI
1444 /* pci-specific processing */
1445 if (pci_dev) {
1446 pci_set_drvdata (pci_dev, dev);
1447 dev->pci_dev = pci_dev;
1448 dev->irq = -pci_dev->irq;
1449 dev->mode &= ~HRT_ISA_MODE;
1450 /* make certain IRQ is disabled before enabling
1451 device, or else we may get an IRQ we are not
1452 prepared to handle? */
1453 hrt_irq_disable(dev);
1454 if (pci_enable_device(pci_dev)) {
1455 HRT_ERROR_MSG("pci_enable_device failed");
1456 hrt_cleanup(dev);
1457 return -EIO;
1458 }
1459 }
1460 #endif
1461
1462 /* find out whether there is an hrt device at this
1463 address, and which type of device it is */
1464
1465 /* save the values we are about to modify */
1466 old_control = ioread8((void *)(HRT_CONTROL_REG + virt_address));
1467 old_y_low = ioread8((void *)(HRT_Y_LOW_REG + virt_address));
1468 old_y_high = ioread8((void *)(HRT_Y_HIGH_REG + virt_address));
1469
1470 /* freeze the frame grabbing, immediately */
1471 iowrite8(0x5B, (void *) (HRT_CONTROL_REG + virt_address));
1472
1473 /* complement pixel (0,0) */
1474 iowrite16(0, (void *) (HRT_Y_LOW_REG + virt_address));
1475 iowrite16(0, (void *) (HRT_Y_HIGH_REG + virt_address));
1476 val1 = ioread8((void *) virt_address);
1477 iowrite8(~val1, (void *) virt_address);
1478
1479 /* write old value of pixel (0,0) to (1,0) */
1480 iowrite16(1, (void *) (HRT_Y_LOW_REG + virt_address));
1481 iowrite8(val1, (void *) virt_address);
1482
1483 /* read the value at the previous raster/row */
1484 iowrite16(0, (void *) (HRT_Y_LOW_REG + virt_address));
1485 val2 = ioread8((void *) virt_address);
1486
1487 if (val2 != (unsigned char)~val1) {
1488 HRT_DEBUG_MSG(1, "no hrt device at address 0x%lx",
1489 virt_address);
1490 /* restore the old values, and hope we did no
1491 damage to some other device at this address;
1492 this is pretty poor, since if there is
1493 another device at that address the effects
1494 of these writes could be harmful;
1495 ideally, there should be a way to
1496 identify the devices that only uses read
1497 operations */
1498 iowrite8(val1, (void *) virt_address);
1499 iowrite8(old_y_low, (void *) (HRT_Y_LOW_REG + virt_address));
1500 iowrite8(old_y_high, (void *) (HRT_Y_HIGH_REG + virt_address));
1501 iowrite8(old_control, (void *) (HRT_CONTROL_REG + virt_address));
1502
1503 hrt_cleanup(dev);
1504 return -ENODEV;
1505 }
1506
1507 /* test whether we have a color or greyscale card:
1508 the color frame buffer has line of 2048 = 0x400
1509 pixels; greyscale has only 512 pixels/line, so
1510 the memory mapped row of frame buffer memory
1511 should wrap around at 0x200 and 0x400 on a greyscale card
1512 but should be good through 0x400 on a color card. */
1513
1514 iowrite8(HRT_FREEZE_IMM_CMD, (void *) (HRT_CONTROL_REG + virt_address));
1515 iowrite16(0, (void *) (HRT_Y_LOW_REG + virt_address));
1516 iowrite16(0, (void *) (HRT_Y_HIGH_REG + virt_address));
1517 val1 = ioread8((void *)(0x400 + virt_address));
1518 iowrite8(~val1, (void *) (0x400 + virt_address));
1519 /* in case greyscale addresses wrap around,
1520 refresh the value at offset zero */
1521 iowrite8(val1, (void *) (virt_address));
1522 val2 = ioread8((void *)(0x400 + virt_address));
1523 if (val2 == (unsigned char) ~val1) {
1524 dev->mode |= HRT_COLOR_MODE;
1525 /* infer the frame geometry from the device type */
1526 HRT_DEBUG_MSG(1, "COLOR device detected");
1527 dev->rows = 480;
1528 dev->cols = 640;
1529 dev->bytes_per_pixel = 2;
1530 } else {
1531 HRT_DEBUG_MSG(1, "GREYSCALE device detected");
1532 dev->cols = 512; /* is for NTSC, 512 for PAL */
1533 dev->rows = 480;
1534 dev->bytes_per_pixel = 1;
1535 }
1536
1537 /* try to initialize the device */
1538 result = hrt_i2c_init_device(dev);
1539 if (result) {
1540 HRT_ERROR_MSG("hrt_i2c_init_device %d failed",result);
1541 hrt_cleanup(dev);
1542 return -ENODEV;
1543 }
1544
1545 hrt_go_live(dev); /* delete this once driver is debugged */
1546
1547 /* find out whether the device has dual-ported memory*/
1548 while (ioread8((void *)(dev->virt_addr + HRT_CONTROL_REG)) & 0x40) {
1549 hrt_printk( "waiting on dual port check\n");
1550 schedule();
1551 }
1552
1553 /* try to overwrite the line with ones */
1554 for (i = 0; i < 512; i++) {
1555 iowrite8(255, (void *) (dev->virt_addr + i));
1556 }
1557
1558 /* freeze the image */
1559 hrt_freeze_immediate(dev);
1560
1561 /* write zeros to horizontal raster line 500,
1562 a line that the A/D unit does not modify */
1563 iowrite16(0, (void *) (dev->virt_addr + HRT_Y_HIGH_REG));
1564 iowrite16(500, (void *) (dev->virt_addr + HRT_Y_LOW_REG));
1565 for (i = 0; i < 512; i++) {
1566 iowrite8(0, (void *)(dev->virt_addr + i));
1567 }
1568
1569 /* set capturing mode */
1570 hrt_go_live(dev);
1571
1572 /* try to overwrite the line with ones */
1573 for (i = 0; i < 512; i++) {
1574 iowrite8(255, (void *) (dev->virt_addr + i));
1575 }
1576
1577 /* freeze the image */
1578 hrt_freeze_immediate(dev);
1579
1580 /* read back the line;
1581 if some of the pixels are still zero the memory is
1582 not dual ported */
1583 result = 1;
1584 for (i = 0; i < 512; i++) {
1585 if (!ioread8((void *)(dev->virt_addr + i))) result = 0;
1586 }
1587 if (result) {
1588 HRT_DEBUG_MSG(1, "seems to be dual ported");
1589 dev->mode |= HRT_DUAL_PORTED_MODE;
1590 }
1591
1592 dev->mode |= HRT_ISA_MODE;
1593
1594 #ifdef CONFIG_PCI
1595 if ((pci_dev->device == HRT_DEVICE_ID_COLOR) !=
1596 ((dev->mode & HRT_COLOR_MODE) == HRT_COLOR_MODE))
1597 HRT_ERROR_MSG("PCI and probed types don't match");
1598 #endif
1599
1600 /* discover whether this device supports interrupts */
1601 hrt_timer_init(dev);
1602 if (dev->mode & HRT_IRQ_MODE) {
1603 /* BASIC IDEA
1604 * Enable the device for 20 ms
1605 * and count the number of interrupts generated
1606 * a non zero value means that this device supports
1607 * IRQs
1608 */
1609 dev->irq_count = 0;
1610 hrt_irq_enable(dev);
1611 hrt_go_live(dev);
1612 mdelay(20);
1613 hrt_freeze_immediate(dev);
1614 hrt_irq_disable(dev);
1615 if (dev->irq_count) {
1616 HRT_DEBUG_MSG(1, "counted %d irqs in 20 ms",
1617 dev->irq_count);
1618 HRT_ERROR_MSG("devices supports IRQs");
1619 } else {
1620 HRT_DEBUG_MSG(1, "no irqs in 20 ms");
1621 dev->irq = 0;
1622 dev->mode &= ~HRT_IRQ_MODE;
1623 }
1624 }
1625
1626 /* describe this device for the log */
1627 if (dev->mode & HRT_ISA_MODE) bus = "ISA";
1628 else bus = "PCI";
1629 if (dev->mode & HRT_COLOR_MODE) color = "COLOR";
1630 else color = "GREYSCALE";
1631 if (dev->mode & HRT_DUAL_PORTED_MODE) ported = "DUAL";
1632 else ported = "SINGLE";
1633 HRT_ERROR_MSG("found device %d at 0x%lx",
1634 dev->num, dev->phys_addr);
1635 HRT_ERROR_MSG("%s %s with %s-ported memory",
1636 bus, color, ported);
1637 if (dev->mode & HRT_IRQ_MODE)
1638 HRT_ERROR_MSG("using IRQ %d", dev->irq);
1639
1640 init_waitqueue_head(&dev->wait_queue);
1641
1642 /* Read the field bit and assign to the field_id variable */
1643 dev->field_id = ioread8((void *)dev->virt_addr + HRT_CONTROL_REG) & 1;
1644 /* Initialize the semaphore */
1645 init_MUTEX(&dev->sem);
1646
1647 /* set default window size
1648 to cover the entire frame buffer */
1649 HRT_DEBUG_MSG(1, "setting width, cols = %d", dev->cols);
1650 dev->win_row = 0;
1651 dev->win_width = dev->cols;
1652 dev->win_col = 0;
1653 dev->win_height = dev->rows;
1654 dev->field = -1;
1655 hrt_num_devices++;
1656 dev->state = HRT_CLOSED_STATE;
1657
1658
1659 /* Make the lists used for streaming empty */
1660 /* Added 2005.06.11 Sean/ Atulya
1661 begin */
1662
1663 INIT_LIST_HEAD(&dev->capture_list.head);
1664 INIT_LIST_HEAD(&dev->done_list.head);
1665
1666 dev->capture_list.length = dev->done_list.length = 0;
1667
1668 /* Initialize the spinlocks to protect the lists */
1669 dev->capture_list.lock = RW_LOCK_UNLOCKED;
1670 dev->done_list.lock = RW_LOCK_UNLOCKED;
1671
1672 /* Register with V4L */
1673 dev->video_dev = videodev_template;
1674 /* Register the video driver */
1675 if (video_register_device(&dev->video_dev, VFL_TYPE_GRABBER,
1676 video_minor) < 0) {
1677 hrt_printk(KERN_ERR "Unable to register video device\n");
1678 /* Failure in the device registration
1679 * Cleanup before exiting
1680 */
1681 hrt_cleanup(dev);
1682 return -ENODEV;
1683 }
1684
1685 /* Set private data (to access through struct file) */
1686 dev->video_dev.priv = dev;
1687
1688 /* Set the constants depending on
1689 * whether the device supports color
1690 * or grey scale
1691 */
1692 if(dev->mode & HRT_COLOR_MODE){
1693 dev->bytesperline = HRT_COLOR_BYTES_PER_LINE;
1694 dev->framesize = HRT_COLOR_FRAMESIZE;
1695 }
1696 else{
1697 dev->bytesperline = HRT_GRAY_BYTES_PER_LINE;
1698 dev->framesize = HRT_GRAY_FRAMESIZE;
1699 }
1700
1701 /* Added 2005.06.11 Sean/ Atulya
1702 end */
1703
1704 /* Allocate the frame buffer */
1705 if (dev->mode & HRT_COLOR_MODE) {
1706 dev->framedata = (unsigned char *) vmalloc(HRT_COLOR_FRAMESIZE);
1707 dev->localbuf = (unsigned char *) kmalloc(sizeof(char) * 1664, GFP_KERNEL);
1708 /* Added 2005.06.11 Sean/ Atulya
1709 begin */
1710 if ((dev->framedata == NULL) || (dev->localbuf == NULL)) {
1711 hrt_printk(KERN_ERR "Unable to allocate memory\n");
1712 //video_unregister_device(&dev->video_dev);
1713 hrt_cleanup(dev);
1714 return -ENOMEM;
1715 }
1716 /* Added 2005.06.11 Sean/ Atulya
1717 end */
1718 }
1719 else {
1720 dev->framedata = (unsigned char *) vmalloc(HRT_GRAY_FRAMESIZE);
1721 dev->localbuf = NULL;
1722 /* Added 2005.06.11 Sean/ Atulya
1723 begin */
1724 if (dev->framedata == NULL) {
1725 hrt_printk(KERN_ERR "Unable to allocate memory\n");
1726 //video_unregister_device(&dev->video_dev);
1727 hrt_cleanup(dev);
1728 return -ENOMEM;
1729 }
1730 /* Added 2005.06.11 Sean/ Atulya
1731 end */
1732 }
1733
1734 /* The device opens in the non streaming mode by default */
1735 dev->streaming = 0;
1736
1737 /* Added 13 June 2005 */
1738 dev->streaming_state = 0;
1739
1740 dev->upside_down = 0;
1741
1742 /* Read the field bit and assign to the field_id */
1743 dev->field_id = hrt_get_field(dev);
1744
1745 /* Make the device go-live */
1746 hrt_go_live(dev);
1747
1748 return 0;
1749 }
1750
1751 /********************************************************************/
1752 int hrt_isa_init(void)
1753 {
1754 int i;
1755 for (i = 0; i < ARRAY_SIZE(hrt_addresses); i++)
1756 hrt_init(hrt_addresses[i], NULL);
1757 hrt_nonpci_devices = hrt_num_devices;
1758 return 0;
1759 }
1760
1761 /********************************************************************/
1762 void hrt_isa_cleanup(void)
1763 {
1764 int i;
1765 for (i=0; i<hrt_nonpci_devices; i++) {
1766 HRT_DEBUG_MSG(2, "cleaning up device %d", i);
1767 hrt_cleanup(hrt_devices+i);
1768 }
1769 }
1770
1771 /*************************
1772 * interrupts and timers *
1773 *************************/
1774
1775 /********************************************************************/
1776 int hrt_irq_pending(hrt_t *dev)
1777 {
1778 int r = ioread8((void *)(dev->virt_addr + HRT_CONTROL_REG)) & 0x4;
1779 rmb();
1780 return r;
1781 }
1782
1783 /********************************************************************/
1784 irqreturn_t hrt_irq_handler(int irq, void* dev_id, struct pt_regs* regs)
1785 {
1786 hrt_t* dev = dev_id;
1787 if (!hrt_irq_pending(dev)) goto none;
1788 /* acknowledge the interrupt */
1789
1790 hrt_irq_disable(dev);
1791 dev->irq_count++;
1792 /* do not try to do any I/O on the device here,
1793 or else risk race with last scheduled tasklet
1794 */
1795 tasklet_schedule(&dev->tasklet);
1796 /* enable the next interrupt */
1797 hrt_irq_enable(dev);
1798 #ifdef IRQ_HANDLED
1799 return IRQ_HANDLED;
1800 #endif
1801 none:
1802 #ifdef IRQ_NONE
1803 return IRQ_NONE;
1804 #endif
1805 }
1806
1807
1808 /********************************************************************/
1809 /**
1810 * streaming_fieldchange_color
1811 *
1812 * Invoked for performing the data reads when streaming
1813 * is in progress
1814 * Called by the timer handler when it determines that
1815 * a complete frame is available for reading into the buffer
1816 *
1817 */
1818 static inline void streaming_fieldchange_color(hrt_t *hrtdev)
1819 {
1820 struct stream_buffer *streambuf;
1821
1822 /* Capture list is empty */
1823 if (!hrtdev->capture_list.length) {
1824 return;
1825 }
1826
1827 streambuf = queue_peek_head(&hrtdev->capture_list);
1828
1829 /* Sanity checks- don't want to do anything bad
1830 in interrupt mode */
1831 if (streambuf == NULL) {
1832 hrt_printk("streambuf is NULL!\n");
1833 return;
1834 }
1835 if (streambuf->vaddress == NULL) {
1836 hrt_printk("vaddress is NULL!\n");
1837 return;
1838 }
1839 if (hrtdev->framedata == NULL) {
1840 hrt_printk("framedata is NULL!\n");
1841 return;
1842 }
1843
1844 /* Depending on the device being color or grey scale
1845 * the buffer would have differant sizes
1846 * clear the entire buffer before writing into it
1847 *
1848 * But only if it is empty !
1849 */
1850 if (streambuf->fields_grabbed == 0 ){
1851 if (hrtdev->mode & HRT_COLOR_MODE)
1852 memset(streambuf->vaddress, 0, HRT_COLOR_FRAMESIZE);
1853 else
1854 memset(streambuf->vaddress, 0, HRT_GRAY_FRAMESIZE);
1855 }
1856
1857 /* Grab the current field and increment the fields_grabbed variable */
1858 grab_field(hrtdev, streambuf->vaddress,hrtdev->field_id);
1859 streambuf->fields_grabbed++;
1860
1861 if(streambuf->fields_grabbed > 2){
1862 /* We have a complete frame */
1863 streambuf->vidbuf.flags |=
1864 V4L2_BUF_FLAG_DONE |
1865 V4L2_BUF_FLAG_KEYFRAME;
1866 /* Move the buffer to the done queue */
1867 queue_del(streambuf, &hrtdev->capture_list);
1868 queue_add_tail(streambuf, &hrtdev->done_list);
1869 hrtdev->field_id = !hrtdev->field_id;
1870 /* Set streaming_state to 0 to repeat the streaming read cycle */
1871 hrtdev->streaming_state = 0;
1872 /* Set fields_grabbed to 0 */
1873 streambuf->fields_grabbed = 0;
1874 /* wake up the user to notify abt the data being available */
1875 wake_up(&hrtdev->wait_queue);
1876 }
1877 }
1878
1879 /********************************************************************/
1880 /**
1881 * streaming_fieldchange_irq
1882 *
1883 * This function used for streaming if we have IRQs running
1884 * Assumes that every interrupt we know that the field has changed
1885 * So faster than using the timer based mechanism
1886 */
1887 static inline void streaming_fieldchange_irq(hrt_t *hrtdev)
1888 {
1889 struct stream_buffer *streambuf;
1890
1891 /* Capture list is empty */
1892 if (!hrtdev->capture_list.length) {
1893 return;
1894 }
1895
1896 streambuf = queue_peek_head(&hrtdev->capture_list);
1897
1898 /* Sanity checks- don't want to do anything bad
1899 in interrupt mode */
1900 if (streambuf == NULL) {
1901 hrt_printk("streambuf is NULL!\n");
1902 return;
1903 }
1904
1905 if (streambuf->vaddress == NULL) {
1906 hrt_printk("vaddress is NULL!\n");
1907 return;
1908 }
1909
1910 if (hrtdev->framedata == NULL) {
1911 hrt_printk("framedata is NULL!\n");
1912 return;
1913 }
1914
1915 /* Now that we have checked everything
1916 * and all buffers seem to be fine
1917 * extract the current field from the device
1918 * and copy to the buffer
1919 */
1920 grab_field(hrtdev, streambuf->vaddress,
1921 !hrtdev->field_id);
1922
1923 streambuf->fields_grabbed++;
1924
1925 /* We have a complete frame */
1926 if (streambuf->fields_grabbed > 1) {
1927 streambuf->fields_grabbed = 0;
1928 streambuf->vidbuf.flags |=
1929 V4L2_BUF_FLAG_DONE |
1930 V4L2_BUF_FLAG_KEYFRAME;
1931
1932 /* Move the buffer to the done queue */
1933 queue_del(streambuf, &hrtdev->capture_list);
1934 queue_add_tail(streambuf, &hrtdev->done_list);
1935 /* notify the wait queue that a frame is available
1936 * for display to the user
1937 */
1938 wake_up(&hrtdev->wait_queue);
1939 }
1940 hrt_printk("streaming_fieldchange ... complete\n");
1941 }
1942
1943
1944 /********************************************************************/
1945 /**
1946 * streaming_fieldchange
1947 *
1948 * if streaming is on, this function is called
1949 * from timer_func when the field_id changes
1950 */
1951 static inline void streaming_fieldchange(hrt_t *hrtdev)
1952 {
1953 struct stream_buffer *streambuf;
1954
1955 /* Capture list is empty */
1956 if (!hrtdev->capture_list.length) {
1957 return;
1958 }
1959
1960 streambuf = queue_peek_head(&hrtdev->capture_list);
1961
1962 /* Sanity checks- don't want to do anything bad
1963 in interrupt mode */
1964 if (streambuf == NULL) {
1965 hrt_printk("streambuf is NULL!\n");
1966 return;
1967 }
1968
1969 if (streambuf->vaddress == NULL) {
1970 hrt_printk("vaddress is NULL!\n");
1971 return;
1972 }
1973
1974 if (hrtdev->framedata == NULL) {
1975 hrt_printk("framedata is NULL!\n");
1976 return;
1977 }
1978
1979 /* Now that we have checked everything
1980 * and all buffers seem to be fine
1981 * extract the current field from the device
1982 * and copy to the buffer
1983 */
1984 grab_field(hrtdev, streambuf->vaddress,
1985 !hrtdev->field_id);
1986
1987 streambuf->fields_grabbed |= (!hrtdev->field_id) + 1;
1988
1989 /* We have a complete frame */
1990 if (streambuf->fields_grabbed == 3) {
1991 streambuf->fields_grabbed = 0;
1992 streambuf->vidbuf.flags |=
1993 V4L2_BUF_FLAG_DONE |
1994 V4L2_BUF_FLAG_KEYFRAME;
1995
1996 /* Move the buffer to the done queue */
1997 queue_del(streambuf, &hrtdev->capture_list);
1998 queue_add_tail(streambuf, &hrtdev->done_list);
1999 /* notify the wait queue that a frame is available
2000 * for display to the user
2001 */
2002 wake_up(&hrtdev->wait_queue);
2003 }
2004 }
2005
2006
2007 /********************************************************************
2008 * hrt_timer_handler
2009 *
2010 * Runs every HZ/100 jiffies
2011 * Core of the driver's functionality in the case where
2012 * we do not have interrupts running on the card.
2013 *
2014 * If we are in the blocking read mode, then this timer
2015 * notifies the reader about field changes, and wakes up
2016 * the reader when a new frame becomes available
2017 *
2018 * If we are in the streaming I/O mode, then the timer
2019 * performs checks on the device field changes
2020 * and invokes the streaming_fieldchange or the streaming_fieldchange_color
2021 * function based on the device's mode.
2022 */
2023 void hrt_timer_handler(unsigned long data)
2024 {
2025 hrt_t* dev = (hrt_t*)data;
2026 if(dev->timer_active){
2027 tasklet_schedule(&dev->tasklet);
2028 /* Schedule the timer to go off in another (HZ/100) jiffies */
2029 dev->timer.expires = jiffies + (HZ/100);
2030 add_timer(&dev->timer);
2031 }
2032 }
2033
2034 /********************************************************************
2035 * hrt_irq_init
2036 *
2037 * Initialises the IRQs, if the device supports interrupts
2038 */
2039 void hrt_irq_init(hrt_t* dev)
2040 {
2041 HRT_DEBUG_MSG(2, "hrt_irq_init");
2042 dev->irq_count = 0;
2043 if (dev->irq == 0) return;
2044 if ((dev->irq > 0) || (dev->mode & HRT_IRQ_MODE)) {
2045 HRT_ERROR_MSG("irq handler already installed");
2046 return;
2047 }
2048 hrt_irq_disable(dev); /* insurance */
2049 if (request_irq(-dev->irq, hrt_irq_handler,
2050 SA_SHIRQ, "hrt", (void*)dev)) {
2051 HRT_ERROR_MSG("unable to reserve IRQ");
2052 dev->irq = 0;
2053 } else {
2054 dev->irq = -dev->irq;
2055 dev->mode |= HRT_IRQ_MODE;
2056 }
2057 }
2058
2059 /********************************************************************
2060 * hrt_irq_cleanup
2061 *
2062 * Cleanup the IRQs
2063 */
2064 void hrt_irq_cleanup(hrt_t* dev)
2065 {
2066 HRT_DEBUG_MSG(2, "hrt_irq_cleanup");
2067 hrt_irq_disable(dev); /* insurance */
2068 if (dev->mode & HRT_IRQ_MODE) {
2069 free_irq(dev->irq, dev);
2070 dev->mode &= ~HRT_IRQ_MODE;
2071 }
2072 }
2073
2074 /*******************************************************************
2075 * hrt_timer_init
2076 *
2077 * If the device supports interrupts then initialise IRQs
2078 * else initialise the timer
2079 */
2080 void hrt_timer_init(hrt_t* dev)
2081 {
2082 HRT_DEBUG_MSG(1, "hrt_timer_init");
2083 HRT_CHECK(dev, HRT_INITIALIZING_STATE, "4");
2084 if (dev->timer_active) {
2085 HRT_ERROR_MSG("irq or timer already active");
2086 /* Commented by Sean & Atulya 2005.06.15
2087 debugging irg
2088 return;
2089 */
2090 }
2091
2092 /* Added 15 june 2005, to add the functionality to use interrupts */
2093 hrt_irq_init(dev);
2094
2095 if (!(dev->mode & HRT_IRQ_MODE)) {
2096 if (dev->timer.function) {
2097 HRT_ERROR_MSG("timer already initialized");
2098 return;
2099 }
2100 HRT_DEBUG_MSG(1, "installing timer\n");
2101 init_timer(&dev->timer);
2102 dev->timer.function = hrt_timer_handler;
2103 dev->timer.data = (unsigned long)dev;
2104 }
2105 }
2106
2107 /********************************************************************
2108 * hrt_timer_cleanup
2109 *
2110 * Cleanup the timer / IRQ
2111 */
2112 void hrt_timer_cleanup(hrt_t* dev)
2113 {
2114 HRT_DEBUG_MSG(1, "hrt_timer_cleanup");
2115 HRT_CHECK(dev, HRT_FINALIZING_STATE, "3");
2116 hrt_timer_deactivate (dev);
2117 /* Added by Sean/ Atulya 2005.06.15
2118 --- begin --- */
2119 tasklet_kill(&dev->tasklet);
2120 /* --- end --- */
2121 hrt_irq_cleanup(dev);
2122 dev->timer.function = NULL;
2123 }
2124
2125 /********************************************************************
2126 * hrt_timer_deactivate
2127 *
2128 * If timer is running then deactivate it else disable the irqs.
2129 * The tasklet runs in both cases. So disable the tasklet
2130 */
2131 void hrt_timer_deactivate(hrt_t* dev)
2132 {
2133 HRT_DEBUG_MSG(1, "hrt_timer_deactivate");
2134 if (dev->timer_active) {
2135 dev->timer_active = 0;
2136 if (dev->mode & HRT_IRQ_MODE){
2137 hrt_irq_disable(dev);
2138 }
2139 else
2140 del_timer_sync(&dev->timer);
2141
2142 // Added 15 june 2005
2143 if (dev->tasklet_active) {
2144 dev->tasklet_active = 0;
2145 tasklet_disable(&dev->tasklet);
2146 }
2147 }
2148 }
2149
2150 /********************************************************************/
2151 /* hrt_timer_activate
2152 *
2153 * Starts a task to monitor the state of the device.
2154 * This may be driven by a timer or by an interrupt
2155 * from the device.
2156 */
2157
2158 int hrt_timer_activate(hrt_t* dev)
2159 {
2160 int result = 0;
2161 HRT_DEBUG_MSG(1, "hrt_timer_activate");
2162
2163 if (dev->timer_active) {
2164 HRT_ERROR_MSG("irq or timer already active");
2165 return 0;
2166 }
2167 dev->timer_active = 1;
2168 if (dev->mode & HRT_IRQ_MODE) {
2169 HRT_DEBUG_MSG(1, "enabling irq");
2170 if (!dev->tasklet_active) {
2171 dev->tasklet_active = 1;
2172 tasklet_enable(&dev->tasklet);
2173 }
2174 hrt_irq_enable(dev);
2175 } else {
2176 if (!dev->timer.function) {
2177 HRT_ERROR_MSG("timer not initialized");
2178 return -1;
2179 }
2180 printk("Enabling the tasklet inside the timer_activate\n");
2181 if (!dev->tasklet_active) {
2182 dev->tasklet_active = 1;
2183 tasklet_enable(&dev->tasklet);
2184 }
2185 dev->timer.expires = jiffies + HZ/100;
2186 add_timer(&dev->timer);
2187 }
2188 return result;
2189 }
2190
2191 /********************************************************************
2192 * hrt_tasklet
2193 *
2194 * The tasklet is the core of the module
2195 * In both IRQ and Timer 'mode' finally the tasklet
2196 * performs the required function
2197 *
2198 * For the irq mode we know that every invocation we have
2199 * a field change
2200 * But for the timer mode, we check every time to see if the
2201 * field_id has changed
2202 *
2203 */
2204 void hrt_tasklet(unsigned long data)
2205 {
2206 int new_field;
2207 hrt_t* dev = (hrt_t*)data;
2208
2209 if (dev->state != HRT_OPEN_STATE) return;
2210
2211 if (hrt_trylock (dev)) { /* device is busy */
2212 return;
2213 }
2214
2215 /* Get the current value of the field bit */
2216 new_field = hrt_get_field (dev);
2217
2218 if (dev->field_id == -1) {
2219 /* just started; don't know previous state */
2220 dev->field_id = new_field;
2221 goto done;
2222 }
2223
2224 /* We need to do something only if the field bit has changed from
2225 * the last value. This would indicate that the field has changed
2226 * from what we read in the last timer execution.
2227 *
2228 * So now we need to take some action if we detect the field change
2229 */
2230
2231
2232 /* CASE 1 - NO IRQs. TIMER RUNNING EVERY HZ/100 JIFFIES */
2233 if (!(dev->mode & HRT_IRQ_MODE)) {
2234 if (dev->streaming) {
2235 /* If we have streaming running, then call the function
2236 * responsible for updating the streaming display
2237 *
2238 * Differant implementations of streaming
2239 * for color and grey scale follow
2240 */
2241 if ((dev->mode & HRT_COLOR_MODE) || !(dev->mode & HRT_DUAL_PORTED_MODE)){
2242 /* if we are in the color mode, we follow differant states
2243 *
2244 * State 0
2245 *
2246 * device goes live
2247 * state changes to 1
2248 *
2249 * State 1
2250 *
2251 * detect 2 field changes
2252 * issue freeze_next command
2253 * move to state 2
2254 *
2255 * State 2
2256 *
2257 * detect 2 field changes
2258 * call the streaming_framechange function
2259 * to read the current frame
2260 * move back to state 0
2261 */
2262 if (dev->streaming_state == 0){
2263 hrt_printk("State 0\n");
2264 if(dev->is_frozen){
2265 hrt_printk("HRT_GO_LIVE\n");
2266 hrt_go_live(dev);
2267 }
2268 else
2269 hrt_printk ("THIS IS AN ERROR\n");
2270 dev->streaming_state = 1;
2271 dev->field_changes = 2;
2272 }
2273 else if (dev->streaming_state == 1){
2274 hrt_printk("State 1 dev->field_changes = %d\n", dev->field_changes);
2275 new_field = hrt_get_field(dev);
2276 if (new_field != dev->field_id){
2277 dev->field_id = new_field;
2278 if(dev->field_changes > 0) dev->field_changes--;
2279 if (dev->field_changes == 0){
2280 dev->streaming_state = 2;
2281 dev->field_changes = 2;
2282 hrt_printk("HRT_FREEZE_NEXT\n");
2283 hrt_freeze_next(dev);
2284 }
2285 }
2286 }
2287 else if (dev->streaming_state == 2){
2288 hrt_printk("State 2 dev->field_changes = %d\n", dev->field_changes);
2289 new_field = hrt_get_field(dev);
2290 if (new_field != dev->field_id){
2291 dev->field_id = new_field;
2292 if(dev->field_changes > 0) dev->field_changes--;
2293 if (dev->field_changes == 0){
2294 dev->streaming_state = 0;
2295 streaming_fieldchange_color(dev);
2296 }
2297 }
2298 }
2299 }
2300 else {
2301 /* Streaming + Grey scale mode
2302 *
2303 * This one not as complicated as the color function
2304 * Just read the current available field
2305 * whenever there is a field change
2306 */
2307 if (new_field != dev->field_id) {
2308 dev->field_id = new_field;
2309 streaming_fieldchange(dev);
2310 }
2311 }
2312 }
2313 else {
2314 /* Not streaming.
2315 * We are in the read mode
2316 * update the reader and let them know that another
2317 * field is available. The reader always waits till we have read
2318 * two fields. Thus he/she/it(?) needs to be notified
2319 * when we read two fields
2320 */
2321 if (new_field != dev->field_id) {
2322 dev->field_id = new_field;
2323 if (dev->field_changes >0) dev->field_changes--;
2324 wake_up_interruptible(&dev->wait_queue);
2325 }
2326 }
2327 }
2328 else {
2329 /* CASE 2 - IRQs ENABLES. AN INTERRUPT RAISED WHENEVER THE FIELD BIT CHANGES */
2330 if (dev->streaming) {
2331 /* If we have streaming running, then call the function
2332 * responsible for updating the streaming display
2333 *
2334 * Differant implementations of streaming
2335 * for color and grey scale follow
2336 */
2337 if ((dev->mode & HRT_COLOR_MODE) || !(dev->mode & HRT_DUAL_PORTED_MODE)){
2338 /* if we are in the color mode, we follow differant states
2339 *
2340 * State 0
2341 *
2342 * device goes live
2343 * state changes to 1
2344 *
2345 * State 1
2346 *
2347 * detect 2 field changes
2348 * issue freeze_next command
2349 * move to state 2
2350 *
2351 * State 2
2352 *
2353 * detect 2 field changes
2354 * call the streaming_framechange function
2355 * to read the current frame
2356 * move back to state 0
2357 */
2358 if (dev->streaming_state == 0){
2359 hrt_printk("State 0\n");
2360 if(dev->is_frozen){
2361 hrt_printk("HRT_GO_LIVE\n");
2362 hrt_go_live(dev);
2363 }
2364 else
2365 hrt_printk ("THIS IS AN ERROR\n");
2366 dev->streaming_state = 1;
2367 dev->field_changes = 2;
2368 }
2369 else if (dev->streaming_state == 1){
2370 hrt_printk("State 1 dev->field_changes = %d\n", dev->field_changes);
2371 new_field = hrt_get_field(dev);
2372 if (new_field != dev->field_id){
2373 dev->field_id = new_field;
2374 if(dev->field_changes > 0) dev->field_changes--;
2375 if (dev->field_changes == 0){
2376 dev->streaming_state = 2;
2377 dev->field_changes = 2;
2378 hrt_printk("HRT_FREEZE_NEXT\n");
2379 hrt_freeze_next(dev);
2380 }
2381 }
2382 }
2383 else if (dev->streaming_state == 2){
2384 hrt_printk("State 2 dev->field_changes = %d\n", dev->field_changes);
2385 new_field = hrt_get_field(dev);
2386 if (new_field != dev->field_id){
2387 dev->field_id = new_field;
2388 streaming_fieldchange_color(dev);
2389 }
2390 }
2391 }
2392 else {
2393 /* Streaming + Grey scale mode
2394 *
2395 * This one not as complicated as the color function
2396 * Just read the current available field
2397 * whenever there is a field change
2398 */
2399 dev->field_id = new_field;
2400 streaming_fieldchange_irq(dev);
2401 }
2402 }
2403 else {
2404 /* Not streaming.
2405 * We are in the read mode
2406 * update the reader and let them know that another
2407 * field is available. The reader always waits till we have read
2408 * two fields. Thus he/she/it(?) needs to be notified
2409 * when we read two fields
2410 */
2411 dev->field_id = new_field;
2412 if (dev->field_changes > 0) dev->field_changes--;
2413 wake_up_interruptible(&dev->wait_queue);
2414 }
2415 }
2416
2417
2418 done:
2419 hrt_unlock(dev);
2420 }
2421
2422 /********************************************************************
2423 * per_file_init
2424 *
2425 * allocates and initializes per-file data, which
2426 * is currently just the ROI (region-of-interest) subwindow
2427 * and a pointer back to this hrtdev
2428 */
2429 struct hrt_per_file *per_file_init(hrt_t *hrtdev)
2430 {
2431 struct hrt_per_file *per_file = vmalloc(sizeof(*per_file));
2432
2433 per_file->hrtdev = hrtdev;
2434 per_file->win.height = HRT_HEIGHT;
2435 if (hrtdev->mode & HRT_COLOR_MODE)
2436 per_file->win.width = HRT_COLOR_WIDTH;
2437 else
2438 per_file->win.width = HRT_GRAY_WIDTH;
2439 per_file->win.startx = 0;
2440 per_file->win.starty = 0;
2441
2442 return per_file;
2443 }
2444
2445
2446 /********************************************************************/
2447 /**
2448 * hrt_open
2449 *
2450 * checks minor number range, sets private_data,
2451 * starts timer if necessary, increments users
2452 */
2453 int hrt_open(struct inode *inode, struct file *file)
2454 {
2455 unsigned int minor;
2456 int result;
2457 /* video device structure required to provide video4linux support */
2458 struct video_device *vfl = video_devdata(file);
2459 hrt_t *dev = vfl->priv;
2460
2461 result = 0;
2462 minor = MINOR(inode->i_rdev);
2463 if (minor >= HRT_MAX_DEVICES) return -ENODEV;
2464
2465 dev = hrt_devices + minor;
2466 HRT_DEBUG_MSG(1, "opening device %d at addr %lX", minor, (unsigned long)dev->phys_addr);
2467
2468 /* Cannot open if device is not in closed state */
2469 if (dev->state != HRT_CLOSED_STATE) {
2470 HRT_DEBUG_MSG(2, "already open");
2471 return -EBUSY;
2472 }
2473 /* Now we set the private data for the device file
2474 * this is in the form of a structure hrt_per_file
2475 * that consists of a hrt_t struct and a subwindow struct
2476 */
2477 HRT_DEBUG_MSG(2, "setting private data");
2478 file->private_data = per_file_init(dev);
2479
2480 /* Set device state to OPEN */
2481 dev->state = HRT_OPEN_STATE;
2482
2483 /* The device opens in the non streaming mode by default */
2484 dev->streaming = 0;
2485
2486 /* Added 13 June 2005 */
2487 dev->streaming_state = 0;
2488
2489 /* Read the field bit and assign to the field_id */
2490 dev->field_id = hrt_get_field(dev);
2491
2492 /* Activate the timer */
2493 HRT_DEBUG_MSG(2, "installing timer/irq");
2494 result = hrt_timer_activate(dev);
2495
2496 return result;
2497 }
2498
2499 /********************************************************************/
2500 /* hrt_release
2501 *
2502 * hrt_release should not need any lock, because
2503 it is only called by the system, on last close; at that
2504 point there should be no possibility of more calls that
2505 touch this device, unless they are from a timer
2506 or interrrupt handler
2507 */
2508
2509 int hrt_release(struct inode *inode, struct file *file)
2510 {
2511 struct video_device *vfl = video_devdata(file);
2512 hrt_t *dev = vfl->priv;
2513
2514 hrt_printk( " hrt_release\n");
2515 if (dev->is_locked) {
2516 hrt_unlock(dev);
2517 }
2518 if (dev->state != HRT_OPEN_STATE) return -ENODEV;
2519 dev->state = HRT_CLOSED_STATE;
2520 hrt_timer_deactivate(dev);
2521
2522 /* Free our private data */
2523 vfree(file->private_data);
2524 return 0;
2525 }
2526
2527 /********************************************************************/
2528 /* hrt_poll
2529 *
2530 * handles poll() and select() on /dev/video<n>
2531 */
2532 unsigned int hrt_poll(struct file *file, poll_table *wait)
2533 {
2534 struct hrt_per_file *per_file = file->private_data;
2535 hrt_t *hrtdev = per_file->hrtdev;
2536
2537 if (!hrtdev->streaming) {
2538 poll_wait(file, &hrtdev->wait_queue, wait);
2539 } else {
2540 /* Go to sleep if the done list is empty */
2541 while (!hrtdev->done_list.length) {
2542 up(&hrtdev->sem);
2543 if (wait_event_interruptible
2544 (hrtdev->wait_queue, (hrtdev->done_list.length)))
2545 return -ERESTARTSYS;
2546
2547 if (down_interruptible(&hrtdev->sem))
2548 return -ERESTARTSYS;
2549 }
2550 }
2551
2552 return POLLIN | POLLRDNORM;
2553 }
2554
2555
2556
2557 /********************************************************************
2558 * hrt_read
2559 *
2560 * Does a blocking read and return count number of bytes back to the user
2561 * Differant implementations for color/grey scale/single ported/dual ported
2562 */
2563 int hrt_read(struct file *file, char *buf, size_t count, loff_t * ppos)
2564 {
2565 int max_count;
2566
2567 /* atulya/sean - to measure the frame rate
2568 * record the jiffies at this time
2569 * then find the jiffies at the time the function returns
2570 * the differance gives the time taken to read one frame
2571 * and thus the frame rate
2572 */
2573 unsigned int starttime;
2574
2575 int old_field;
2576 struct video_device *vfl = video_devdata(file);
2577 hrt_t *dev = vfl->priv;
2578
2579 HRT_DEBUG_MSG(3, "hrt_read count = %d", count);
2580 if (dev->state != HRT_OPEN_STATE) return -ENODEV;
2581
2582
2583 //hrt_printk( "hrt_read: (start) jiffies = %ld\n", jiffies);
2584 starttime = jiffies;
2585
2586 if (dev->mode & HRT_COLOR_MODE) {
2587 /* First implementation - COLOR device
2588 *
2589 * These ones are single ported so
2590 * need to wait till the entire field gets digitized before we can read it
2591 * This is a conservative approach..and wastes an extra frame just to make
2592 * sure that we get the correct frame boundary.
2593 * Can be tweaked to make it faster
2594 */
2595 hrt_lock(dev);
2596 dev->field_changes = 2;
2597 if (dev->is_frozen) {
2598 hrt_go_live (dev);
2599 hrt_unlock(dev);
2600 /* Go live
2601 * and
2602 * wait for two field changes
2603 */
2604 if (wait_event_interruptible(dev->wait_queue, dev->field_changes == 0)) {
2605 return -ERESTARTSYS;
2606 }
2607 hrt_lock(dev);
2608 dev->field_changes = 2;
2609 }
2610 hrt_freeze_next(dev);
2611 hrt_unlock(dev);
2612 /* Now we know that we are at a frame bondary
2613 * Wait for 2 field changes
2614 * and at that time we can read both fields as one frame
2615 */
2616 if (wait_event_interruptible(dev->wait_queue, dev->field_changes == 0)) {
2617 return -ERESTARTSYS;
2618 }
2619 /* Cannot return more bytes than what the device sends to us
2620 * Check for that */
2621 max_count = dev->win->width * dev->win->height * dev->bytes_per_pixel;
2622 if (count > max_count) count = max_count;
2623
2624 if (down_interruptible(&dev->sem))
2625 return -ERESTARTSYS;
2626
2627 old_field = dev->field_id;
2628
2629 /* Grab a field */
2630 grab_field(dev, dev->framedata, old_field);
2631
2632 /* Grab the other field */
2633 grab_field(dev, dev->framedata,(!old_field) );
2634 }
2635 else {
2636 /* Implementation 2 - GREY SCALE DULA ported device
2637 *
2638 * These devices are dual ported so we can
2639 * read at a faster rate
2640 * Dont need the extra checking required in the
2641 * case of single ported devices.
2642 * Results in a faster rate
2643 *
2644 * Just grab one field,
2645 * wait for a field change
2646 * and grab the other field
2647 */
2648 if (dev->mode & HRT_DUAL_PORTED_MODE) {
2649 max_count = dev->win->width * dev->win->height * dev->bytes_per_pixel;
2650 if (count > max_count) count = max_count;
2651 down_interruptible(&dev->sem);
2652 old_field = dev->field_id;
2653
2654 /* Grab a field */
2655 grab_field(dev, dev->framedata, old_field);
2656
2657 /* Go to sleep until the field bit changes */
2658 while (old_field == dev->field_id) {
2659 up(&dev->sem);
2660 if (file->f_flags & O_NONBLOCK)
2661 return -EAGAIN;
2662
2663 if (wait_event_interruptible
2664 (dev->wait_queue, (old_field != dev->field_id)))
2665 return -ERESTARTSYS;
2666
2667 if (down_interruptible(&dev->sem))
2668 return -ERESTARTSYS;
2669 }
2670
2671 /* Grab the other field */
2672 grab_field(dev, dev->framedata, dev->field_id);
2673 }
2674 else {
2675 /* Imlementation 3 - GREYSCALE SINGLE ported device
2676 *
2677 * Again similar implementation as the color devices
2678 */
2679 hrt_lock(dev);
2680 dev->field_changes = 2;
2681 if (dev->is_frozen) {
2682 hrt_go_live (dev);
2683 hrt_unlock(dev);
2684 if (wait_event_interruptible(dev->wait_queue, dev->field_changes == 0)) {
2685 return -ERESTARTSYS;
2686 }
2687 hrt_lock(dev);
2688 dev->field_changes = 2;
2689 }
2690 hrt_freeze_next(dev);
2691 hrt_unlock(dev);
2692 if (wait_event_interruptible(dev->wait_queue, dev->field_changes == 0)) {
2693 return -ERESTARTSYS;
2694 }
2695
2696 max_count = dev->win->width * dev->win->height * dev->bytes_per_pixel;
2697 if (count > max_count) count = max_count;
2698
2699 if (down_interruptible(&dev->sem))
2700 return -ERESTARTSYS;
2701
2702 old_field = dev->field_id;
2703
2704 /* Grab a field */
2705 grab_field(dev, dev->framedata, old_field);
2706
2707 /* Grab the other field */
2708 grab_field(dev, dev->framedata,(!old_field) );
2709 }
2710 }
2711
2712 /* Both returned fields have been stored in their corresponding
2713 * location inside the dev->framedata buffer
2714 * Return to the user
2715 */
2716 if (copy_to_user(buf, dev->framedata, count)) {
2717 up(&dev->sem);
2718 return -EFAULT;
2719 }
2720 /* Clear the buffer */
2721 if (dev->mode & HRT_COLOR_MODE)
2722 memset(dev->framedata, 0, HRT_COLOR_FRAMESIZE);
2723 else
2724 memset(dev->framedata, 0, HRT_GRAY_FRAMESIZE);
2725
2726
2727 up(&dev->sem);
2728 /* (1/ (time taken to read one frame)) = frame rate */
2729 hrt_printk( " Frame rate = %d\n", (int)( HZ / (jiffies-starttime) ) );
2730 return count;
2731 }
2732
2733 /********************************************************************
2734 *
2735 * v4l1_ioctls - used for printing out ioctl codes in hrt_do_ioctl
2736 */
2737 static const char *v4l1_ioctls[] = {
2738 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT",
2739 "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
2740 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
2741 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
2742 "SMICROCODE", "GVBIFMT", "SVBIFMT"
2743 };
2744
2745
2746 /********************************************************************
2747 *
2748 * hrt_do_ioctl - handles ioctl's on /dev/video<n>
2749 */
2750 static int hrt_do_ioctl(struct inode *inode, struct file *file,
2751 unsigned int cmd, void *arg)
2752 {
2753 struct hrt_per_file *per_file = file->private_data;
2754 hrt_t *hrtdev = per_file->hrtdev;
2755 hrtdev->win = &per_file->win;
2756
2757 /* This nice code copied from xawtv's libng.
2758 It prints out the ioctl's that are done.
2759 */
2760 switch (_IOC_TYPE(cmd)) {
2761 case 'v':
2762 dprintk("ioctl 0x%x (v4l1, VIDIOC%s)\n",
2763 cmd, (_IOC_NR(cmd) < ARRAY_SIZE(v4l1_ioctls)) ?
2764 v4l1_ioctls[_IOC_NR(cmd)] : "???");
2765 break;
2766 case 'V':
2767 dprintk("ioctl 0x%x (v4l2, %s)\n",
2768 cmd, v4l2_ioctl_names[_IOC_NR(cmd)]);
2769 break;
2770 default:
2771 dprintk("ioctl 0x%x (?)\n", cmd);
2772 }
2773
2774 switch (cmd) {
2775 case IOC_HRT_FREEZE_FRAME:
2776 HRT_DEBUG_MSG(2, "IOC_HRT_FREEZE_FRAME: called");
2777 hrt_freeze_next(hrtdev);
2778 break;
2779
2780 case IOC_HRT_GO_LIVE:
2781 HRT_DEBUG_MSG(2, "IOC_HRT_GO_LIVE: called");
2782 hrt_go_live(hrtdev);
2783 break;
2784 case IOC_HRT_UPSIDE_DOWN:
2785 HRT_DEBUG_MSG(2, "IOC_HRT_UPSIDE_DOWN: called");
2786 if (hrtdev->upside_down)
2787 hrtdev->upside_down = 0;
2788 else
2789 hrtdev->upside_down = 1;
2790 break;
2791
2792 /* Streaming ioctl's */
2793 case VIDIOC_REQBUFS: {
2794 struct v4l2_requestbuffers *req = arg;
2795
2796 if (hrtdev->stream_buffers_mapped) {
2797 hrt_printk("REQBUFS - Can't request buffers if "
2798 " buffers are already mapped\n");
2799 return -EPERM;
2800 }
2801 if (!mmap_request_buffers(hrtdev, req)) {
2802 hrt_printk("REQBUFS - Request of buffers failed\n");
2803 return -EINVAL;
2804 }
2805 return 0;
2806 }
2807 case VIDIOC_QUERYBUF: {
2808 struct v4l2_buffer *buf =
2809 (struct v4l2_buffer *) arg;
2810 int i;
2811 i = buf->index;
2812
2813
2814 if (i < 0 || i >= MAX_CAPTURE_BUFFERS ||
2815 !hrtdev->stream_buf[i].requested ||
2816 (buf->type & V4L2_BUF_TYPE_VIDEO_CAPTURE) !=
2817 (hrtdev->stream_buf[i].vidbuf.type & V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
2818 hrt_printk("QUERYBUF - bad parameter\n");
2819 return -EINVAL;
2820 }
2821
2822 *buf = hrtdev->stream_buf[i].vidbuf;
2823 return 0;
2824 }
2825 case VIDIOC_QBUF: {
2826 struct v4l2_buffer *buf =
2827 (struct v4l2_buffer *) arg;
2828
2829 if (!hrtdev->stream_buffers_mapped) {
2830 return -EINVAL;
2831 }
2832
2833 if (!hrt_queuebuffer(hrtdev, buf)) {
2834 return -EINVAL;
2835 }
2836 return 0;
2837 }
2838 case VIDIOC_DQBUF: {
2839 struct v4l2_buffer *buf =
2840 (struct v4l2_buffer *) arg;
2841
2842 if (!hrt_dequeuebuffer(hrtdev, buf)) {
2843 return -EINVAL;
2844 }
2845 return 0;
2846 }
2847 case VIDIOC_STREAMON: {
2848 __u32 *type = (__u32 *) arg;
2849 if (!hrt_streamon(hrtdev, *type))
2850 return -EINVAL;
2851 return 0;
2852 }
2853 case VIDIOC_STREAMOFF: {
2854 __u32 *type = (__u32 *) arg;
2855 hrt_streamoff(hrtdev, *type);
2856 return 0;
2857 }
2858
2859 /* Non-streaming ioctl's */
2860 case VIDIOC_QUERYCAP: {
2861 struct v4l2_capability *b =
2862 (struct v4l2_capability *) arg;
2863
2864 strcpy(b->driver, "hrt");
2865 strncpy(b->card, "PS 512-8-PCI", sizeof(b->card));
2866 sprintf(b->bus_info,"PCI:%s", hrtdev->pci_dev->slot_name);
2867 b->version = KERNEL_VERSION(0, 0, 2);
2868
2869 if (disable_streaming) {
2870 b->capabilities =
2871 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
2872 } else {
2873
2874
2875 b->capabilities =
2876 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
2877 V4L2_CAP_STREAMING;
2878 }
2879 return 0;
2880 }
2881 case VIDIOC_ENUM_FMT: {
2882 struct v4l2_fmtdesc *f = arg;
2883 enum v4l2_buf_type type = f->type;
2884 int index = f->index;
2885
2886 /* There's only one format */
2887 if (index > 0)
2888 return -EINVAL;
2889
2890 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2891 memset(f, 0, sizeof(*f));
2892 f->index = index;
2893 f->type = type;
2894 if(hrtdev->mode & HRT_COLOR_MODE){
2895 f->pixelformat = V4L2_PIX_FMT_RGB555; //check this one
2896 strcpy(f->description, "Color");
2897 }
2898 else{
2899 f->pixelformat = V4L2_PIX_FMT_GREY;
2900 strcpy(f->description, "Grey");
2901 }
2902
2903 return 0;
2904 } else {
2905 return -EINVAL;
2906 }
2907 }
2908 case VIDIOC_TRY_FMT:
2909 case VIDIOC_S_FMT:
2910 case VIDIOC_G_FMT: {
2911 struct v4l2_format *f = arg;
2912
2913 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2914
2915 memset(&f->fmt.pix, 0,
2916 sizeof(struct v4l2_pix_format));
2917 f->fmt.pix.width = hrtdev->win->width;
2918 f->fmt.pix.height = hrtdev->win->height;
2919
2920 if(hrtdev->mode & HRT_COLOR_MODE)
2921 f->fmt.pix.pixelformat = V4L2_PIX_FMT_RGB555;
2922 else
2923 f->fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;
2924
2925 f->fmt.pix.bytesperline = hrtdev->bytesperline;
2926 f->fmt.pix.sizeimage = hrtdev->framesize;
2927 hrt_printk("pix.width (%d), pic.height (%d)",
2928 f->fmt.pix.width, f->fmt.pix.height);
2929 hrt_printk("pix.bytesperline (%d), pic.sizeimage (%d)",
2930 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
2931 return 0;
2932 } else {
2933 return -EINVAL;
2934 }
2935 }
2936
2937 case VIDIOC_G_CROP: {
2938 struct v4l2_crop * win = arg;
2939
2940 win->c.height = hrtdev->win->height;
2941 win->c.width = hrtdev->win->width;
2942 win->c.top = hrtdev->win->starty;
2943 win->c.left = hrtdev->win->startx;
2944
2945 return 0;
2946 }
2947
2948 case VIDIOC_S_CROP: {
2949 struct v4l2_crop *win = arg;
2950
2951 hrtdev->win->height = win->c.height;
2952 hrtdev->win->width = win->c.width;
2953 hrtdev->win->starty = win->c.top;
2954 hrtdev->win->startx = win->c.left;
2955
2956 return 0;
2957
2958 }
2959
2960 case VIDIOC_G_STD: {
2961 v4l2_std_id *id = arg;
2962
2963 *id = V4L2_STD_NTSC;
2964 return 0;
2965 }
2966 case VIDIOC_S_STD: {
2967 /* There's only one standard that we support, NTSC */
2968 return 0;
2969 }
2970 case VIDIOC_QUERYCTRL: {
2971 struct v4l2_queryctrl *c = arg;
2972 int i;
2973
2974 for (i = 0; i < ARRAY_SIZE(hrt_ctls); i++)
2975 if (hrt_ctls[i].id == c->id)
2976 break;
2977
2978 /* Didn't find the id */
2979 if (i == ARRAY_SIZE(hrt_ctls)) {
2980 return -EINVAL;
2981 }
2982
2983 *c = hrt_ctls[i];
2984 return 0;
2985 }
2986 case VIDIOC_G_CTRL: {
2987 struct v4l2_control *c = arg;
2988 int i;
2989
2990 for (i = 0; i < ARRAY_SIZE(hrt_ctls); i++)
2991 if (hrt_ctls[i].id == c->id)
2992 break;
2993
2994 if (i == sizeof(hrt_ctls))
2995 return -EINVAL;
2996
2997 if (c->id == V4L2_CID_BRIGHTNESS) {
2998 /*
2999 c->value = hrtdev->regvals[HRT_BRIGHTNESS_REG];
3000 */
3001 c->value = hrtdev->saa7110_registers[HRT_BRIGHTNESS_REG];
3002 } else if (c->id == V4L2_CID_CONTRAST) {
3003 /*
3004 c->value = hrtdev->regvals[HRT_CONTRAST_REG];
3005 */
3006 c->value = hrtdev->saa7110_registers[HRT_BRIGHTNESS_REG];
3007
3008 } else {
3009 return -EINVAL;
3010 }
3011
3012 return 0;
3013 }
3014 case VIDIOC_S_CTRL: {
3015 /*
3016 struct v4l2_control *c = arg;
3017 int i;
3018
3019 for (i = 0; i < sizeof(hrt_ctls); i++)
3020 if (hrt_ctls[i].id == c->id)
3021 break;
3022 if (i == sizeof(hrt_ctls))
3023 return -EINVAL;
3024
3025 if (c->id == V4L2_CID_BRIGHTNESS) {
3026 if (c->value > 255)
3027 return -EINVAL;
3028 c->value = i2c_set_reg(hrtdev, HRT_BRIGHTNESS_REG,
3029 c->value);
3030 } else if (c->id == V4L2_CID_CONTRAST) {
3031 if (c->value > 255)
3032 return -EINVAL;
3033 c->value = i2c_set_reg(hrtdev, HRT_CONTRAST_REG,
3034 c->value);
3035 } else {
3036 return -EINVAL;
3037 }
3038 */
3039 return 0;
3040 }
3041 case VIDIOC_ENUMINPUT: {
3042 struct v4l2_input *i = arg;
3043 unsigned int n;
3044
3045 /* Only one input */
3046 if (i->index > 0)
3047 return -EINVAL;
3048
3049 n = i->index;
3050 memset(i, 0, sizeof(*i));
3051 i->index = n;
3052 i->type = V4L2_INPUT_TYPE_CAMERA;
3053 sprintf(i->name, "NTSC Camera");
3054
3055 return 0;
3056 }
3057 case VIDIOC_ENUMSTD: {
3058 struct v4l2_standard *e = arg;
3059 struct v4l2_fract fract = { 1001, 30000 };
3060 unsigned int index = e->index;
3061
3062 /* One standard (NTSC) */
3063 if (index > 0)
3064 return -EINVAL;
3065
3066 e->id = V4L2_STD_NTSC_M;
3067 e->index = index;
3068 strcpy(e->name, "NTSC");
3069 e->frameperiod = fract;
3070 e->framelines = hrtdev->win->height;
3071
3072 return 0;
3073 }
3074 case VIDIOC_G_PARM: {
3075 struct v4l2_streamparm *parm = arg;
3076 struct v4l2_standard s;
3077
3078 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3079 return -EINVAL;
3080 memset(parm, 0, sizeof(*parm));
3081
3082 v4l2_video_std_construct(&s, V4L2_STD_NTSC,
3083 "NTSC");
3084 parm->parm.capture.timeperframe = s.frameperiod;
3085 return 0;
3086 }
3087 case VIDIOC_G_INPUT: {
3088 return 0;
3089 }
3090 case VIDIOC_S_INPUT: {
3091 return 0;
3092 }
3093 default:
3094 return -ENOIOCTLCMD;
3095 }
3096
3097 return 0;
3098 }
3099
3100 /********************************************************************
3101 * hrt_ioctl
3102 *
3103 * handler for ioctl's on /dev/video<n>. Tries the private
3104 * ioctl's first, via hrt_do_private_ioctl().
3105 */
3106 int hrt_ioctl(struct inode *inode, struct file *file,
3107 unsigned int cmd, unsigned long arg)
3108 {
3109 struct hrt_per_file *per_file = file->private_data;
3110 hrt_t *hrtdev = per_file->hrtdev;
3111 int ret;
3112 hrtdev->win = &per_file->win;
3113
3114 dprintk("ioctl arg = %lx\n", arg);
3115
3116 down(&hrtdev->sem);
3117
3118 ret = hrt_do_private_ioctl(hrtdev, cmd, arg);
3119 if (ret != -EINVAL) {
3120 up(&hrtdev->sem);
3121 return ret;
3122 }
3123 ret = video_usercopy(inode, file, cmd, arg, hrt_do_ioctl);
3124 up(&hrtdev->sem);
3125 return ret;
3126 }
3127
3128 #ifdef CONFIG_PCI
3129
3130 /***************
3131 * PCI support *
3132 ***************/
3133
3134 /********************************************************************/
3135 MODULE_DEVICE_TABLE(pci, hrt_pci_tbl);
3136 int hrt_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id);
3137 void hrt_pci_remove (struct pci_dev *pci_dev);
3138
3139 /********************************************************************/
3140 static struct pci_device_id hrt_pci_tbl[] __devinitdata = {
3141 {PCI_DEVICE(HRT_VENDOR_ID, HRT_DEVICE_ID_GREY)},
3142 {PCI_DEVICE(HRT_VENDOR_ID, HRT_DEVICE_ID_COLOR)},
3143 {0,}
3144 };
3145
3146 /********************************************************************/
3147 static struct pci_driver hrt_pci_driver = {
3148 .name = "hrt",
3149 .id_table = hrt_pci_tbl,
3150 .probe = hrt_pci_probe,
3151 .remove = __devexit_p(hrt_pci_remove)
3152 };
3153
3154 /********************************************************************/
3155 int hrt_pci_probe(struct pci_dev *pci_dev,
3156 const struct pci_device_id *pci_id)
3157 {
3158 HRT_DEBUG_MSG(2, "probing pci device");
3159
3160 /* check that this is a type of device we support */
3161 if ((pci_dev->device != HRT_DEVICE_ID_COLOR) &&
3162 (pci_dev->device != HRT_DEVICE_ID_GREY)) {
3163 HRT_ERROR_MSG("unknown device type 0x%hx",
3164 pci_dev->device);
3165 return -ENODEV;
3166 }
3167
3168 if (hrt_num_devices >= HRT_MAX_DEVICES) {
3169 HRT_ERROR_MSG("need to increase HRT_MAX_DEVICES");
3170 return -ENOMEM;
3171 }
3172
3173
3174 return hrt_init(pci_resource_start(pci_dev, 0), pci_dev);
3175 }
3176
3177 /********************************************************************/
3178 /* since these cards are not intended to be hot-pluggable,
3179 we do not try to reuse hrt_t objects; we just use the remove
3180 operation for removal of the device driver module */
3181
3182 void hrt_pci_remove (struct pci_dev *pci_dev)
3183 {
3184 hrt_t *dev;
3185 HRT_DEBUG_MSG(2, "hrt_pci_remove");
3186 dev = (hrt_t *) pci_get_drvdata (pci_dev);
3187 hrt_cleanup(dev);
3188
3189 /* Added by Sean/ Atulya 2005.06.14
3190 * -- begin -- */
3191 video_unregister_device(&dev->video_dev);
3192 /* -- end -- */
3193
3194 pci_disable_device(pci_dev);
3195 }
3196
3197 /********************************************************************/
3198 void hrt_pci_init(void)
3199 {
3200 HRT_DEBUG_MSG(2, "pci_register_driver");
3201 pci_register_driver(&hrt_pci_driver);
3202 }
3203
3204 /********************************************************************/
3205 void hrt_pci_cleanup(void)
3206 {
3207 hrt_printk( " hrt_pci_cleanup\n");
3208 HRT_DEBUG_MSG(2, "pci_unregister_driver");
3209 pci_unregister_driver(&hrt_pci_driver);
3210 }
3211
3212 #else
3213
3214 /* no PCI support */
3215
3216 /********************************************************************/
3217 void hrt_pci_init(void)
3218 {
3219 }
3220
3221 /********************************************************************/
3222 void hrt_pci_cleanup(void)
3223 {
3224 hrt_printk( " no pci support hrt_pci_cleanup\n");
3225 }
3226
3227 #endif
3228
3229 /*************************************
3230 * module initialization and cleanup *
3231 *************************************/
3232
3233 int hrt_major_number = 0;
3234
3235 /********************************************************************/
3236 void hrt_cleanup_module(void)
3237 {
3238 hrt_printk( " initiating hrt_cleanup_module\n");
3239 HRT_MODULE_CHECK (HRT_MODULE_INITIALIZING_STATE |
3240 HRT_MODULE_INITIALIZED_STATE, "6");
3241 hrt_module_state = HRT_MODULE_FINALIZING_STATE;
3242 HRT_DEBUG_MSG(2, "hrt_cleanup_module");
3243 hrt_printk( " calling hrt_isa_cleanup\n");
3244 hrt_isa_cleanup();
3245 hrt_printk( " calling hrt_pci_cleanup\n");
3246 hrt_pci_cleanup();
3247 hrt_printk( " unregistering the 'hrt' device\n");
3248 if (hrt_major_number) unregister_chrdev(hrt_major_number, "hrt");
3249 hrt_printk( " calling hrt_debug_cleanup\n");
3250 hrt_debug_cleanup();
3251 hrt_module_state = HRT_MODULE_UNINITIALIZED_STATE;
3252 hrt_printk( " cleanup completed\n");
3253 }
3254
3255 /********************************************************************/
3256 int hrt_init_module(void)
3257 {
3258 int result = 0;
3259
3260 hrt_module_state = HRT_MODULE_INITIALIZING_STATE;
3261 hrt_debug_init();
3262
3263 /* Added 2005.06.11 Sean/ Atulya
3264 begin */
3265 memset(hrt_devices, 0, sizeof(hrt_devices));
3266
3267 /* use major number returned by system if no
3268 major number is specified by this module */
3269 if (major_number == 0) hrt_major_number = result;
3270 else hrt_major_number = major_number;
3271 HRT_ERROR_MSG("module initializing with major number %d",
3272 hrt_major_number);
3273
3274 /* detect ISA/PC104 devices, and PCI devices that are
3275 jumpered to use the ISA/PC104 I/O address space */
3276 hrt_isa_init();
3277
3278 hrt_pci_init();
3279
3280 /* now detect regular PCI devices */
3281 if (hrt_num_devices == 0) {
3282 HRT_ERROR_MSG("no hrt devices detected");
3283 hrt_module_state = HRT_MODULE_UNINITIALIZED_STATE;
3284 return -ENODEV;
3285 } else {
3286 HRT_ERROR_MSG("found %d hrt devices", hrt_num_devices);
3287 }
3288 hrt_module_state = HRT_MODULE_INITIALIZED_STATE;
3289 return 0;
3290 }
3291
3292 /********************************************************************/
3293 /**
3294 * hrt_vma_open - increments reference count
3295 */
3296 static void hrt_vma_open(struct vm_area_struct *vma)
3297 {
3298 struct video_device *vdev = video_devdata(vma->vm_file);
3299 hrt_t *hrtdev = vdev->priv;
3300 struct stream_buffer *buf;
3301
3302 hrt_printk( "hrt_vma_open\n");
3303 if (hrtdev == NULL)
3304 return;
3305 buf = mmap_stream_buffer_from_offset(hrtdev, vma->vm_pgoff);
3306 if (buf == NULL)
3307 return;
3308 else {
3309 hrt_printk("hrt_vma_open : buf allocated at (0x%lx)", (unsigned long)buf);
3310 }
3311
3312 buf->vma_refcount++;
3313
3314 }
3315
3316 /********************************************************************/
3317 /**
3318 * hrt_vma_close - decrements reference count of a stream buffer
3319 */
3320 static void hrt_vma_close(struct vm_area_struct *vma)
3321 {
3322 struct video_device *vdev = video_devdata(vma->vm_file);
3323 hrt_t *hrtdev = vdev->priv;
3324 struct stream_buffer *buf;
3325
3326 if (hrtdev == NULL)
3327 return;
3328
3329 buf = mmap_stream_buffer_from_offset(hrtdev, vma->vm_pgoff);
3330 buf->vma_refcount--;
3331
3332 if (buf->vma_refcount > 0) {
3333 return;
3334 }
3335 if (hrtdev->streaming) {
3336 hrt_printk(KERN_WARNING "munmap() called while streaming\n");
3337 hrt_streamoff(hrtdev, buf->vidbuf.type);
3338 }
3339 if (buf->vaddress != NULL) {
3340 vfree(buf->vaddress);
3341 buf->vaddress = NULL;
3342 }
3343 buf->vidbuf.flags = 0;
3344
3345 if (hrtdev->stream_buffers_mapped > 0)
3346 hrtdev->stream_buffers_mapped--;
3347 }
3348
3349 /********************************************************************/
3350 /**
3351 * hrt_vma_nopage - calls kvirt_to_pa to convert the vaddress in the
3352 * stream buffer (indexed via the offset parameter to mmap()) to
3353 * a page number for access from userspace
3354 */
3355 struct page *hrt_vma_nopage(struct vm_area_struct *vma,
3356 unsigned long address, int * type)
3357 {
3358 struct video_device *vdev = video_devdata(vma->vm_file);
3359 hrt_t *hrtdev = vdev->priv;
3360
3361 struct stream_buffer *buf;
3362 unsigned long offset_into_buf;
3363 struct page *page;
3364
3365 buf = mmap_stream_buffer_from_offset(hrtdev, vma->vm_pgoff);
3366 if (buf == NULL)
3367 return 0;
3368 offset_into_buf = address - vma->vm_start;
3369 if (offset_into_buf >= buf->vidbuf.length) {
3370 hrt_printk("Attempt to read past end of mmap() buffer\n");
3371 return 0;
3372 }
3373 page = vmalloc_to_page(buf->vaddress + offset_into_buf);
3374 if (page != NULL)
3375 atomic_inc(&page->_count);
3376 return page;
3377 }
3378
3379
3380 /********************************************************************/
3381 /**
3382 * hrt_vm_ops - vm operations on /dev/video<n>
3383 */
3384 struct vm_operations_struct hrt_vm_ops = {
3385 .open = hrt_vma_open,
3386 .close = hrt_vma_close,
3387 .nopage = hrt_vma_nopage,
3388 };
3389
3390
3391 /********************************************************************/
3392 int hrt_queuebuffer( hrt_t *hrtdev,
3393 struct v4l2_buffer *vidbuf)
3394 {
3395 int i = vidbuf->index;
3396 struct stream_buffer *buf = NULL;
3397
3398 if ( !(hrtdev->stream_buffers_mapped) ) {
3399 return 0;
3400 }
3401 if (vidbuf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3402 hrt_printk("QBUF - wrong type (type = %x)\n", vidbuf->type);
3403 return 0;
3404 }
3405 if (i < 0 || i >= MAX_CAPTURE_BUFFERS
3406 || !hrtdev->stream_buf[i].requested) {
3407 hrt_printk("QBUF - buffer index %d is out of range\n", i);
3408 return 0;
3409 }
3410 buf = &hrtdev->stream_buf[i];
3411
3412 hrt_printk("hrt_queuebuffer : buf (0x%lx)", (unsigned long)buf);
3413
3414 if (!(buf->vidbuf.flags & V4L2_BUF_FLAG_MAPPED)) {
3415 hrt_printk("QBUF - buffer %d is not mapped\n", i);
3416 return 0;
3417 }
3418 if ((buf->vidbuf.flags & V4L2_BUF_FLAG_QUEUED)) {
3419 hrt_printk("QBUF - buffer %d is already queued\n", i);
3420 return 0;
3421 }
3422 buf->vidbuf.flags &= ~V4L2_BUF_FLAG_DONE;
3423 queue_add_tail(buf, &hrtdev->capture_list);
3424 buf->vidbuf.flags |= V4L2_BUF_FLAG_QUEUED;
3425 return 1;
3426 }
3427
3428
3429 /********************************************************************/
3430 /**
3431 * hrt_dequeuebuffer - called by the DQBUF ioctl.
3432 * Returns a buffer from the done queue.
3433 */
3434 int hrt_dequeuebuffer(hrt_t *hrtdev,
3435 struct v4l2_buffer *buf)
3436 {
3437 struct stream_buffer *newbuf;
3438 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3439 hrt_printk("DQBUF - Wrong buffer type\n");
3440 return 0;
3441 }
3442 newbuf = queue_del_head(&hrtdev->done_list);
3443 if (newbuf == NULL) {
3444 hrt_printk("DQBUF - No buffers on done queue\n");
3445 return 0;
3446 }
3447 newbuf->vidbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
3448 *buf = newbuf->vidbuf;
3449
3450 return 1;
3451 }
3452
3453
3454 /********************************************************************/
3455 /**
3456 * mmap_request_buffers - called by the ioctl REQBUF to request buffers
3457 */
3458 int mmap_request_buffers(hrt_t *dev, struct v4l2_requestbuffers *req)
3459 {
3460 int i;
3461 u32 buflen;
3462 u32 type;
3463
3464 if (req->count < 1)
3465 req->count = 1;
3466 if (req->count > MAX_CAPTURE_BUFFERS)
3467 req->count = MAX_CAPTURE_BUFFERS;
3468 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3469
3470 /* The buffer length needs to be a multiple of the page size */
3471 buflen = (dev->framesize + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
3472 hrt_printk("Granting %d buffers, buflen (%d)\n", req->count, buflen);
3473
3474 /* Now initialize the buffer structures. Don't allocate the
3475 buffers until they're mapped. */
3476 for (i = 0; i < req->count; i++) {
3477 dev->stream_buf[i].requested = 1;
3478 dev->stream_buf[i].vidbuf.index = i;
3479 dev->stream_buf[i].vidbuf.type = type;
3480 /* offset must be unique for each buffer, and a multiple
3481 of PAGE_SIZE on 2.4.x */
3482 dev->stream_buf[i].vidbuf.m.offset = PAGE_SIZE * (i + 1);
3483 dev->stream_buf[i].vidbuf.length = buflen;
3484 dev->stream_buf[i].vidbuf.bytesused = 0;
3485 dev->stream_buf[i].vidbuf.flags = 0;
3486 /* XXX: should set timestamp? */
3487 dev->stream_buf[i].vidbuf.sequence = 0;
3488 dev->stream_buf[i].vma_refcount = 0;
3489 dev->stream_buf[i].vaddress = NULL;
3490 memset(&dev->stream_buf[i].vidbuf.timecode, 0,
3491 sizeof(struct v4l2_timecode));
3492 }
3493 for (i = req->count; i < MAX_CAPTURE_BUFFERS; i++)
3494 dev->stream_buf[i].requested = 0;
3495 dev->stream_buffers_requested = req->count;
3496
3497 return 1;
3498 }
3499
3500 /********************************************************************/
3501 /**
3502 * hrt_mmap - called by the mmap() system call on /dev/video<n>
3503 */
3504 int hrt_mmap(struct file *file, struct vm_area_struct *vma)
3505 {
3506 struct video_device *dev = video_devdata(file);
3507 hrt_t *hrtdev = dev->priv;
3508 struct stream_buffer *buf = NULL;
3509
3510 down(&hrtdev->sem);
3511
3512 hrt_printk("hrt_mmap\n");
3513
3514 if (next_mmap_is_direct) {
3515 int ret;
3516 next_mmap_is_direct = 0;
3517 ret = hrt_direct_mmap(file, vma);
3518 up(&hrtdev->sem);
3519 return ret;
3520 }
3521
3522 buf = mmap_stream_buffer_from_offset(hrtdev, vma->vm_pgoff);
3523
3524 if (buf == NULL) {
3525 hrt_printk("mmap() - Invalid offset parameter\n");
3526 up(&hrtdev->sem);
3527 return -EINVAL;
3528 }
3529 if (buf->vidbuf.length != vma->vm_end - vma->vm_start) {
3530 hrt_printk("mmap() - Bad length parameter\n");
3531 up(&hrtdev->sem);
3532 return -EINVAL;
3533 }
3534 if (!buf->requested) {
3535 hrt_printk("mmap() - Buffer is not available for mapping\n");
3536 up(&hrtdev->sem);
3537 return -EINVAL;
3538 }
3539 if (buf->vidbuf.flags & V4L2_BUF_FLAG_MAPPED) {
3540 hrt_printk("mmap() - Buffer is already mapped\n");
3541 up(&hrtdev->sem);
3542 return -EINVAL;
3543 }
3544 if (buf->vaddress != NULL)
3545 vfree(buf->vaddress);
3546 /*
3547 * Allocate virtual memory. This memory is mapped to the
3548 * buffer in user space.
3549 */
3550 buf->vaddress = vmalloc(buf->vidbuf.length);
3551 if (buf->vaddress == NULL) {
3552 hrt_printk("Could not allocate mmap() buffer\n");
3553 up(&hrtdev->sem);
3554 return -ENODEV;
3555 }
3556 else {
3557 hrt_printk("Successfully allocated mmap() buffer\n");
3558 }
3559
3560 buf->vidbuf.flags |= V4L2_BUF_FLAG_MAPPED;
3561 hrtdev->stream_buffers_mapped++;
3562 vma->vm_ops = &hrt_vm_ops;
3563 if (vma->vm_ops->open)
3564 vma->vm_ops->open(vma);
3565
3566 up(&hrtdev->sem);
3567 return 0;
3568 }
3569
3570 /********************************************************************/
3571 /**
3572 * hrt_streamon - called by the STREAMON ioctl.
3573 */
3574 int hrt_streamon(hrt_t *hrtdev, __u32 type)
3575 {
3576 struct stream_buffer *buf;
3577
3578 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3579 printk("STREAMON - Wrong buffer type\n");
3580 return 0;
3581 }
3582
3583 /* Move any leftover done buffers to the free pool */
3584 while ((buf = queue_del_head(&hrtdev->done_list)))
3585 buf->vidbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
3586
3587 hrtdev->streaming = 1;
3588 hrt_printk("Streaming is turned on\n");
3589
3590 return 1;
3591 }
3592
3593 /********************************************************************/
3594
3595 module_init(hrt_init_module);
3596 module_exit(hrt_cleanup_module);
3597
3598 MODULE_LICENSE("GPL");
3599
|
This page was automatically generated by the
LXR engine.
|