1 /*
2 * hrt_dev.c
3 *
4
5 WARNING:
6 -------
7 The current version of this code is incomplete. Only the device
8 probing and initialization code is believed to be correct.
9
10 This is a bare-bones device driver for the PixelSmart512-8 (greyscale)
11 and Video Gala (color) framegrabbers. For more information on these
12 devices, see http://www.pixelsmart.com.
13
14 Unlike earlier drivers for these cards from FSU, this driver does *not*
15 attempt to support the Video4Linux (V4L) API, nor does it use the generic
16 Linux I2C support code.
17
18 We have intentionally removed all dependencies of V4L, because:
19
20 (1) This board is so basic that most of the V4L API (e.g.,
21 tuning, audio) is not applicable..
22 (2) At this time, the V4L API seems sufficiently unstable to cause
23 us worries about backward and forward compatibility.
24 That is, we don't want to have to worry about differences in V4L
25 headers and kernel modules breaking this driver.
26 (3) Users of this card for embedded applications do not want to
27 waste kernel memory for the V4L code if they are not using it.
28 (4) We don't know of any demand for using these cards with
29 existing V4L applications.
30
31 We have intentionally removed all dependecies on the Linux generic I2C
32 core (i2c.h and i2c-dev.h) because:
33
34 (1) The Linux generic i2c support code added both logical
35 complexity and code size, and did not work reliably for this card.
36 (2) The Linux I2C core has changed enough over time, and we expect it
37 will change further. We don't want to have to worry about such
38 differences between versions breking this driver.
39 (3) this card has enough idiosyncracies that there is very little potential
40 reuse of code between this I2C bus and other I2C applications.
41 (4) Users of this card for embedded applications do not want to
42 waste kernel memory for the extra code.
43
44 -----------------------------------------
45
46 This version does only supports blocking reads.
47 I deleted the support for streaming, because it needs to be done
48 differently for single-ported and dual-ported cards,
49 and I did not have time to work out the best way to allow for
50 both cases within one framework.
51
52 Blocking read operation:
53
54 1. Initiate digitization, and start the timer/handler if necessary.
55 2. Wait for a frame to become available and frozen.
56 3. Copy frame to user memory.
57
58 Timer handler/Frame Interrupt Handler:
59
60 Keep track of fields, and when a full frame is captured,
61 freeze the card and unblock the reader at step (2) above.
62
63 Locking rules for direct I/O access to the device:
64
65 We cannot allow concurrent access to the device, lest
66 it be confused by sequences of commands that are interleaved.
67 Mutual exclusion is guaranteed as follows:
68
69 (1) The holder of dev->spinlock can do I/O on the device.
70 (2) The IRQ/timer handler uses spin_lock/unlock, and normally
71 scheduled code uses spin_lock/unlock_irqsave/restore.
72 (3) Since we don't want to keep interrupts disabled the whole
73 time we copy data from the device, we use an additional
74 variable, dev->is_locked, to keep the timer handler from
75 touching the device while copying is going on from a
76 process context.
77
78 */
79
80 #ifndef __KERNEL__
81 #define __KERNEL__
82 #endif
83
84 #include <linux/config.h>
85 #include <linux/delay.h> /* udelay */
86 #include <linux/errno.h> /* error codes */
87 #include <linux/file.h>
88 #include <linux/fs.h>
89 #include <linux/interrupt.h>
90 #include <linux/ioport.h>
91 #include <linux/kernel.h>
92 #include <linux/mm.h>
93 #include <linux/module.h>
94 #include <linux/pci.h>
95 #include <linux/proc_fs.h>
96 #include <linux/sched.h>
97 #include <linux/slab.h>
98 #include <linux/spinlock.h>
99 #include <linux/version.h>
100 #include <linux/config.h>
101 #include <linux/moduleparam.h>
102 #include <linux/interrupt.h>
103 #include <asm/io.h>
104 #include <asm/segment.h>
105 #include <asm/uaccess.h>
106
107 #include "hrt.h"
108
109 #define HRT_DEBUG
110
111 #define HRT_ERROR_MSG(args...) do{printk("<1>hrt: "); printk(args);\
112 printk("\n");}while(0)
113
114 /*********************
115 * Module Parameters *
116 *********************/
117
118 #ifndef module_param
119 #define hrt_parm(name, pstr, type, perm) MODULE_PARM(name, pstr)
120 #else
121 #define hrt_parm(name, pstr, type, perm) module_param(name, type, perm)
122 #endif
123
124 static
125 int major_number = 82;
126 hrt_parm(major_number, "i", int, 0);
127
128 #ifndef HRT_MAX_DEVICES
129 #define HRT_MAX_DEVICES 4
130 #endif
131
132 #ifndef HRT_IO_SIZE
133 #define HRT_IO_SIZE 0x4000
134 #endif
135
136 /**
137 * hrt_addresses - a list of possible jumper-selected addresses
138 * jumper A on = plug and play address (above one MB address)
139 * jumper A off = hardwired to 0xdc000 or 0xd4000
140 * jumper B on = address 0xd4000 (ignored if jumper A is on)
141 * jumper B off = address 0xdc000 (ignored if jumper A is on)
142 */
143 const unsigned long hrt_addresses[] = { 0xd4000, 0xdc000 };
144
145 /***************************
146 * Card-specific constants *
147 ***************************/
148
149 #define HRT_VENDOR_ID 0x0004
150 #define HRT_DEVICE_ID_GREY 0x0404
151 #define HRT_DEVICE_ID_COLOR 0x0408
152
153 /* Number of registers on the board- checked in i2c_init() */
154 #define HRT_SAA7110_MAXREG 0x34
155
156 /**
157 * HRT device descriptor
158 */
159 typedef struct {
160 int num;
161 int state;
162 /* minor device number, index in hrt_devices[] */
163 unsigned long virt_addr;
164 unsigned long phys_addr;
165 /* cannot be opened again until released */
166
167 /* spinlock and is_locked control access to the device */
168 spinlock_t spinlock;
169 int is_locked;
170 wait_queue_head_t wait_queue;
171 struct timer_list timer;
172 struct tasklet_struct tasklet;
173 int timer_active;
174 /* timer_active != 0 iff timer or irq is active */
175 int irq;
176 /* irq != 0 if board supports interrupts
177 = -irq if handler not installed
178 = irq if handler is installed */
179 volatile
180 int irq_count;
181 volatile
182 int i2c_bits;
183 /* last values written to i2c */
184 char saa7110_registers[HRT_SAA7110_MAXREG+1];
185 /* video data format, and dependent values */
186 int mode;
187 int rows, cols, bytes_per_pixel;
188 int win_row, win_col, win_width, win_height;
189 /* current field being digitized */
190 int field;
191 /* how many field changes we are waiting for */
192 int field_changes;
193 /* the device is either frozen or being frozen */
194 int is_frozen;
195 #ifdef CONFIG_PCI
196 struct pci_dev *pci_dev;
197 #endif
198 } hrt_t;
199
200 /* values for field hrt_t->state */
201 #define HRT_UNINITIALIZED_STATE 1
202 #define HRT_INITIALIZING_STATE 2
203 #define HRT_CLOSED_STATE 4
204 #define HRT_OPEN_STATE 8
205 #define HRT_FINALIZING_STATE 16
206
207 /* values for field hrt_t->mode */
208 #define HRT_DUAL_PORTED_MODE 1
209 #define HRT_COLOR_MODE 2
210 #define HRT_STREAMING_MODE 4
211 #define HRT_IRQ_MODE 8
212 #define HRT_ISA_MODE 16
213
214 /* values for global hrt_module_state */
215
216 #define HRT_MODULE_UNINITIALIZED_STATE 1
217 #define HRT_MODULE_INITIALIZING_STATE 2
218 #define HRT_MODULE_INITIALIZED_STATE 4
219 #define HRT_MODULE_FINALIZING_STATE 8
220
221 int hrt_module_state = HRT_MODULE_UNINITIALIZED_STATE;
222
223 int hrt_nonpci_devices = 0; /* number of non-pci devices detected */
224 /* non-pci devices have lower numbers */
225 int hrt_num_devices = 0; /* total number of devices detected */
226
227 #define HRT_IS_PCI(X) ((X) >= hrt_nonpci_devices)
228
229 /* ??? consider dynamically allocating the device
230 objects as they are probed and detectg, and
231 using a linked list here instead of an array */
232
233 hrt_t hrt_devices[HRT_MAX_DEVICES];
234
235
236 #ifdef HRT_DEBUG
237 /******************************
238 * optional debugging support *
239 ******************************/
240
241 #define HRT_DEBUG_LEVEL 3
242
243 #define HRT_CHECK(dev,states,msg) \
244 {if (dev->state & ~(states))\
245 {HRT_DEBUG_MSG(1, "* unexpected state 0x%2x (%s)", dev->state, msg);}}
246
247 #define HRT_MODULE_CHECK(states,msg) \
248 {if (hrt_module_state & ~(states))\
249 {HRT_DEBUG_MSG(1, "* unexpected state 0x%2x (%s)", hrt_module_state, msg);}}
250
251 #define HRT_DEBUG_MSG(level,args...) {if (level <= HRT_DEBUG_LEVEL)\
252 {printk("<1>hrt * "); printk(args); printk("\n");}}
253
254 struct proc_dir_entry *hrt_proc_read_entry = NULL;
255
256 #define write_buf(args...) \
257 do { \
258 n = snprintf(buf, count, args); \
259 buf += n; \
260 count -= n; \
261 } while(0)
262
263 int hrt_read_proc(char *buf, char **start, off_t offset,
264 int count, int *eof, void *data)
265 {
266 int n, i;
267 int ips, tps, rps;
268 char *org_buf = buf;
269
270 ips = 0;
271 tps = 0;
272 rps = 0;
273
274 /* dont excede count bytes when writing to buf */
275 /* just write to buf as a normal ptr to a file */
276
277 write_buf("dev HZ/10 int timer read int/s timer/s read/s\n");
278 for (i=0; i<HRT_MAX_DEVICES; i++) {
279 write_buf("%6i %6i %7i %9i %8i\n", i,
280 hrt_devices[i].irq_count,
281 ips, tps, rps);
282 }
283 *eof = 1;
284 return buf - org_buf;
285 }
286
287 #define hrt_debug_init()\
288 { hrt_proc_read_entry = create_proc_read_entry("hrt0", 0, 0, hrt_read_proc, 0);}
289
290 #define hrt_debug_cleanup()\
291 {if (hrt_proc_read_entry) remove_proc_entry("hrt", 0);}
292
293 #else
294 /* hrt debugging is off */
295
296 #define HRT_CHECK(dev,states,msg) do{}while(0)
297 #define HRT_MODULE_CHECK(states,msg) do{}while(0)
298 #define HRT_DEBUG_MSG(args...) do{}while(0)
299 #define hrt_debug_init() do{}while(0)
300 #define hrt_debug_cleanup() do{}while(0)
301 #endif
302
303 /****************************
304 * low-level device control *
305 ****************************/
306
307 /* I2C bits */
308 #define HRT_I2C_SCL 0x01
309 #define HRT_I2C_SDA 0x02
310
311 #define HRT_CONTROL(addr) (addr + HRT_CONTROL_REG)
312 #define I2C_CONTROL(addr) (addr + HRT_I2C_REG)
313 #define I2C_BUSY(addr) (!(ioread8((void *) HRT_CONTROL(addr)) & 0x80))
314
315 /* Bit 7 at 0x2000 (the HRT512-8 control register) tells whether
316 * the CPU is sending data across the I2C bus */
317
318 #define hrt_freeze_next(dev) \
319 dev->is_frozen = 1;\
320 iowrite8(HRT_FREEZE_NEXT_CMD, (void *) (dev->virt_addr + HRT_CONTROL_REG))
321 #define hrt_freeze_immediate(dev) \
322 dev->is_frozen = 1;\
323 iowrite8(HRT_FREEZE_IMM_CMD, (void *) (dev->virt_addr + HRT_CONTROL_REG))
324 #define hrt_go_live(dev) \
325 dev->is_frozen = 0;\
326 iowrite8(HRT_LIVE_CMD, (void *) (dev->virt_addr + HRT_CONTROL_REG))
327 #define hrt_get_field(dev) \
328 ioread8((void *) (dev->virt_addr + HRT_CONTROL_REG)) & 0x1
329 #define hrt_i2c_delay() udelay(5)
330
331 /* Unique I2C bus address of the SAA7110 (A/D) device */
332 #define HRT_AD_DEVICE_ID (128+16+8+4)
333
334 const unsigned char saa7110_default_init_regs[] = {
335 94, /* there are 94 bytes that follow */
336 0x00, 0x4c, /* increment delay (IDEL) */
337 0x01, 0x3c, /* HSY begin 50 Hz */
338 0x02, 0x0d, /* HSY stop 50 Hz */
339 0x03, 0xef, /* HCL begin 50 Hz */
340 0x04, 0xbd, /* HCL stop 50 Hz */
341 0x05, 0xf0, /* HSY after PHI1 50 Hz */
342 0x06, 0x00, /* luminance control */
343 0x07, 0x00, /* hue control */
344 0x08, 0xf8, /* colour killer threshold QUAM (PAL/NTSC) */
345 0x09, 0xf8, /* colour killer threshold SECAM */
346 0x0A, 0x60, /* PAL switch sensitivity */
347 0x0B, 0x50, /* SECAM switch sensitivity */
348 0x0C, 0x00, /* gain control chrominance */
349 0x0D, 0x86, /* standard/mode control */
350 /* 7 VTRC = 1 (VCR mode, not TV)
351 6 XXX
352 5 XXX
353 4 XXX
354 3 RTSE = 0 (PLIN switched to output)
355 2 HRMV = 1 (HREF normal position)
356 1 SSTB = 1 (status byte = 1)
357 0 SECS = 0 (other standards, not SECAM) */
358 0x0E, 0x18, /* I/O and clock control */
359 0x0F, 0x90, /* control #1 */
360 0x10, 0x00, /* control #2 */
361 0x11, 0x2c, /* chrominance gain reference */
362 0x12, 0x7f, /* chrominance saturation */
363 0x13, 0x5e, /* luminance contrast */
364 0x14, 0x42, /* HSY begin 60 Hz */
365 0x15, 0x1a, /* HSY stop 60 Hz */
366 0x16, 0xff, /* HCL begin 60 Hz */
367 0x17, 0xda, /* HCL stop 60 Hz */
368 0x18, 0xf0, /* HSY after PHI1 60 Hz */
369 0x19, 0x9b, /* luminance brightness */
370 /*
371 0x1A - not used
372 0x1B - not used
373 0x1C - not used
374 0x1D - not used
375 0x1E - not used
376 0x1F - not used
377 */
378 0x20, 0x7c, /* analog control #1 */
379 0x21, 0x03, /* analog control #2 */
380 0x22, 0xd2, /* mixer control #1 */
381 0x23, 0x41, /* clamping level control 21 */
382 0x24, 0x80, /* clamping level control 22 */
383 0x25, 0x41, /* clamping level control 31 */
384 0x26, 0x80, /* clamping level control 32 */
385 0x27, 0x4f, /* gain control #1 */
386 0x28, 0xfe, /* white peak control */
387 0x29, 0x01, /* sync bottom control */
388 0x2A, 0xcf, /* gain control analog #2 */
389 0x2B, 0x0f, /* gain control analog #3 */
390 0x2C, 0x83, /* mixer control #2 */
391 0x2D, 0x01, /* integration value gain */
392 0x2E, 0x81, /* vertical blanking pulse set */
393 0x2F, 0x03, /* vertical blanking pulse reset */
394 0x30, 0x60, /* ADCs gain control */
395 0x31, 0x71, /* mixer control #3 */
396 0x32, 0x02, /* integration value white peak */
397 0x33, 0x8c, /* mixer control #4 */
398 0x34, 0x03, /* gain update level */
399 };
400
401 /*
402 * sda = set data bit on I2C bus
403 * to the value given by parameter high
404 */
405 static inline
406 void hrt_sda(hrt_t *dev, unsigned long addr, int high)
407 {
408 if (high) dev->i2c_bits |= HRT_I2C_SDA;
409 else dev->i2c_bits &= ~HRT_I2C_SDA;
410 iowrite8(dev->i2c_bits, (void *) I2C_CONTROL(addr));
411 wmb();
412 }
413
414 /*
415 * scl = set clock bit on I2C bus
416 * to the value given by parameter high
417 */
418 static inline
419 void hrt_scl(hrt_t *dev, unsigned long addr, int high)
420 {
421 if (high) dev->i2c_bits |= HRT_I2C_SCL;
422 else dev->i2c_bits &= ~HRT_I2C_SCL;
423 iowrite8(dev->i2c_bits, (void *) I2C_CONTROL(addr));
424 wmb();
425 }
426
427 /*
428 * sda_scl = set data and clock bits on I2C bus
429 * to the values given by parameters sda_high and scl_high
430 */
431 static inline
432 void hrt_sda_scl(hrt_t *dev,
433 unsigned long addr, int sda_high, int scl_high)
434 {
435 if (sda_high) dev->i2c_bits |= HRT_I2C_SDA;
436 else dev->i2c_bits &= ~HRT_I2C_SDA;
437 if (scl_high) dev->i2c_bits |= HRT_I2C_SCL;
438 else dev->i2c_bits &= ~HRT_I2C_SCL;
439 iowrite8(dev->i2c_bits, (void *) I2C_CONTROL(addr));
440 wmb();
441 }
442
443 /*
444 * sda_read = read data bit from I2C control register
445 */
446 static inline
447 int hrt_sda_read(unsigned long addr)
448 { char c = ioread8((void *) I2C_CONTROL(addr)); return (c & HRT_I2C_SDA); }
449
450 /*
451 * hrt_i2c_start = start I2C data transmission
452 */
453 static inline
454 void hrt_i2c_start(hrt_t *dev, unsigned long addr)
455 {
456 hrt_sda_scl(dev, addr, 0, 0);
457 hrt_i2c_delay();
458 hrt_sda(dev, addr, 1);
459 hrt_i2c_delay();
460 hrt_scl(dev, addr, 1);
461 hrt_i2c_delay();
462 hrt_sda(dev, addr, 0);
463 hrt_i2c_delay();
464 hrt_scl(dev, addr, 0);
465 }
466
467 /*
468 * hrt_i2c_stop = end I2C data transmission
469 */
470 static inline
471 void hrt_i2c_stop(hrt_t *dev, unsigned long addr)
472 {
473 hrt_sda_scl(dev, addr, 0, 0);
474 hrt_i2c_delay();
475 hrt_scl(dev, addr, 1);
476 hrt_i2c_delay();
477 hrt_sda(dev, addr, 1);
478 hrt_i2c_delay();
479 hrt_scl(dev, addr, 0);
480 hrt_scl(dev, addr, 1);
481 }
482
483 /*
484 * hrt_i2c_send_bit
485 */
486 static
487 int hrt_i2c_send_bit(hrt_t *dev,
488 unsigned long addr, unsigned char bit)
489 {
490 unsigned long timeout;
491 if (bit) hrt_sda(dev, addr, 1);
492 else hrt_sda(dev, addr, 0);
493 hrt_i2c_delay();
494 iowrite8(dev->i2c_bits | 0x04, (void *) I2C_CONTROL(addr));
495 wmb();
496 hrt_i2c_delay();
497 if (I2C_BUSY(addr)) {
498 timeout = jiffies + HZ/10;
499 while (I2C_BUSY(addr)) {
500 if (jiffies > timeout) {
501 HRT_ERROR_MSG("i2c bus timeout");
502 return -1;
503 }
504 }
505 }
506 return 0;
507 }
508
509 /*
510 * hrt_i2c_send_byte
511 */
512 static
513 int hrt_i2c_send_byte(hrt_t *dev, unsigned long addr, unsigned char data)
514 {
515 char bitpos, bit;
516 for(bitpos = 0; bitpos < 8; bitpos++) {
517 bit = (data & 0x80) >> 7;
518 data <<= 1;
519 if(hrt_i2c_send_bit(dev, addr, bit)) goto failure;
520 }
521 hrt_i2c_delay();
522 hrt_sda_scl(dev, addr, 1, 0);
523 hrt_scl(dev, addr, 1); /* leave clock high */
524 udelay(10);
525 if (hrt_sda_read(addr)) {
526 HRT_ERROR_MSG("no i2c ack");
527 goto failure;
528 }
529 hrt_sda_scl(dev, addr, 1, 0);
530 return 0;
531 failure:
532 hrt_sda_scl(dev, addr, 1, 0);
533 hrt_i2c_stop(dev, addr);
534 return -1;
535 }
536
537 /*
538 * hrt_i2c_init_registers
539 *
540 * sends a sequence of values to the A/D converter device over the I2C bus.
541 * For an example of the format of "sequence" see the declaration of
542 * saa7110_default_init_regs[] above. The first byte is the number of
543 * data bytes that follow. The rest of the sequence is a series of pairs
544 * of a register number followed by a value. It is better if the values
545 * are sorted in increasing order of register number, but the sequence may
546 * have gaps and need not be in order.
547 */
548 int hrt_i2c_init_registers(hrt_t *dev, const char *sequence)
549 {
550 unsigned long addr;
551 int i, len, cur_reg;
552
553 len = (int) (*sequence++);
554 addr = dev->virt_addr;
555
556 if (len <= 2) {
557 HRT_ERROR_MSG("invalid register initialization sequence");
558 return -1;
559 }
560
561 hrt_i2c_start(dev, addr);
562
563 /* here we select the A/D Device on the i2c bus
564 * that should pay attention to the following bytes */
565 if (hrt_i2c_send_byte(dev, dev->virt_addr, HRT_AD_DEVICE_ID)) {
566 HRT_ERROR_MSG("send_byte failed");
567 return -1;
568 }
569
570 /* start at the first register and increment along the way */
571 if (hrt_i2c_send_byte(dev, dev->virt_addr, cur_reg = sequence[0])) {
572 HRT_ERROR_MSG("send_byte failed(2)");
573 return -1;
574 }
575
576 for(i = 0; i < len; i += 2, sequence += 2) {
577 char reg = sequence[0];
578 char data = sequence[1];
579 if (reg > HRT_SAA7110_MAXREG) {
580 HRT_ERROR_MSG("register %02X out of range!", reg);
581 return -1;
582 }
583 if (reg != cur_reg) {
584
585 /* we're going to an entirely different register */
586 hrt_i2c_stop(dev, addr);
587 hrt_i2c_start(dev, addr);
588
589 /* select the chip/device on the bus */
590 if (hrt_i2c_send_byte(dev, dev->virt_addr, HRT_AD_DEVICE_ID)) {
591 HRT_ERROR_MSG("send_byte failed(3)");
592 return -1;
593 }
594
595 /* select the register */
596 if (hrt_i2c_send_byte(dev, dev->virt_addr, cur_reg = reg)) {
597 HRT_ERROR_MSG("send_byte failed(4)");
598 return -1;
599 }
600 }
601
602 if (hrt_i2c_send_byte(dev, dev->virt_addr, data)) {
603 HRT_ERROR_MSG("send_byte failed(5)");
604 return -1;
605 }
606 dev->saa7110_registers[cur_reg++] = data;
607 }
608 /* free the i2c bus */
609 hrt_i2c_stop(dev, addr);
610 return 0;
611 }
612
613 int hrt_i2c_init_device(hrt_t *dev)
614 {
615 int result = 0;
616 HRT_DEBUG_MSG(2, "hrt_i2c_init_device entered"
617 " (virt_addr = %08X, addr = %08X)",
618 (unsigned) dev->virt_addr,
619 (unsigned) dev->phys_addr);
620
621 result = hrt_i2c_init_registers(dev, saa7110_default_init_regs);
622 if (result) {
623 HRT_ERROR_MSG("hrt_i2c_init_registers failed %d", result);
624 return result;
625 }
626 HRT_DEBUG_MSG(2, "hrt_i2c_init_device returning %d", result);
627 return result;
628 }
629
630 /***************************
631 * buffering, data copying *
632 ***************************/
633
634 /*
635 * hrt_copy_window
636 *
637 * copy entire window from video device to buffer
638 * assume frame is frozen
639 */
640
641 int hrt_copy_window(hrt_t *dev, char * buf)
642 {
643 unsigned long y_addr;
644 unsigned long in_addr;
645 int win_width, win_height, win_end, win_col, win_row;
646 int i, j, y;
647 int dev_line_length;
648
649 y_addr = dev->virt_addr + HRT_Y_LOW_REG;
650 win_width = dev->win_width;
651 win_height = dev->win_height;
652 win_row = dev->win_row;
653 win_col = dev->win_col;
654 in_addr = dev->virt_addr + win_col;
655
656 if (~(dev->mode & HRT_COLOR_MODE)) {
657 dev_line_length = 512;
658 win_end = dev->win_row + dev->win_height;
659 for (y = win_row * dev_line_length; y < win_end; y++) {
660 iowrite16(y, (void *) y_addr);
661 wmb();
662 if (copy_to_user(buf, (void *) in_addr, win_width)) {
663 HRT_ERROR_MSG("copy_to_user failed %lx %lx %d %d (1)",
664 (unsigned long) in_addr, (unsigned long) buf,
665 win_width, y);
666 return -EFAULT;
667 }
668 buf += win_width;
669 }
670 } else if (dev->mode & HRT_COLOR_MODE) {
671 dev_line_length = 2048;
672 win_end = dev->win_row + dev->win_height;
673 for (y = win_row * dev_line_length; y < win_end; y++) {
674 iowrite16(y, (void *) y_addr);
675 wmb();
676 if (copy_to_user(buf, (void *) in_addr, win_width)) {
677 HRT_ERROR_MSG("copy_to_user failed (2)");
678 return -EFAULT;
679 }
680 /* rearrange pixels into logical order */
681 for (i = 0; i < win_width; i++) {
682 j = i + win_col;
683 if (j < 512) {
684 buf[i] = buf[j];
685 buf[i+1] = buf[j+512];
686 } else {
687 buf[i] = buf[j+512];
688 buf[i+1] = buf[j+1024];
689 }
690 }
691 buf += win_width;
692 }
693 } else {
694 HRT_ERROR_MSG("unsupported format %x", dev->mode);
695 }
696 return 0;
697 }
698
699 /*************************************
700 * device initialization and cleanup *
701 *************************************/
702
703 static inline
704 void hrt_irq_enable(hrt_t *dev)
705 {
706 int val;
707 val = ioread8((void *)(dev->virt_addr + HRT_IRQ_ENABLE));
708 val |= 0x1;
709 iowrite8(val, (void *) (dev->virt_addr + HRT_IRQ_ENABLE));
710 }
711
712 static inline
713 void hrt_irq_disable(hrt_t *dev)
714 {
715 int val;
716 val = ioread8((void *)(dev->virt_addr + HRT_IRQ_ENABLE));
717 val &= ~0x1;
718 iowrite8(val, (void *) (dev->virt_addr + HRT_IRQ_ENABLE));
719 }
720
721 void hrt_tasklet(unsigned long);
722 void hrt_timer_init(hrt_t* dev);
723 void hrt_timer_cleanup(hrt_t* dev);
724 int hrt_timer_activate(hrt_t* dev);
725 void hrt_timer_deactivate(hrt_t* dev);
726
727 void hrt_cleanup(hrt_t* dev)
728 {
729 HRT_DEBUG_MSG(1, "shutting down hrt device %d at 0x%lx",
730 dev->num, dev->phys_addr);
731 HRT_MODULE_CHECK (HRT_MODULE_FINALIZING_STATE |
732 HRT_MODULE_INITIALIZING_STATE, "1");
733 HRT_CHECK (dev, HRT_INITIALIZING_STATE
734 | HRT_CLOSED_STATE | HRT_FINALIZING_STATE, "2");
735 dev->state = HRT_FINALIZING_STATE;
736
737 /* restore device to an inactive state */
738 hrt_freeze_next(dev);
739
740 /* deactivate and remove interrupt handler or timer */
741 hrt_timer_cleanup (dev);
742
743 if (dev->phys_addr) {
744 HRT_DEBUG_MSG(2, "release_mem_region 0x%lx, 0x%lx",
745 (unsigned long)dev, (unsigned long) dev->phys_addr);
746 release_mem_region(dev->phys_addr, HRT_IO_SIZE);
747 dev->phys_addr = 0;
748 }
749 if (dev->virt_addr) {
750 HRT_DEBUG_MSG(2, "iounmap %lx", (unsigned long) dev->virt_addr);
751 iounmap((void *)dev->virt_addr);
752 dev->virt_addr = 0;
753 }
754 #ifdef CONFIG_PCI
755 if (dev->pci_dev) {
756 pci_disable_device(dev->pci_dev);
757 dev->pci_dev = NULL;
758 }
759 #endif
760 dev->state = HRT_UNINITIALIZED_STATE;
761 }
762
763 void hrt_lock_init(hrt_t * dev) {
764 spin_lock_init(&dev->spinlock);
765 dev->is_locked = 0;
766 }
767
768 int hrt_trylock(hrt_t * dev) {
769 spin_lock(&dev->spinlock);
770 if (dev->is_locked) {
771 spin_unlock(&dev->spinlock);
772 return 1;
773 }
774 dev->is_locked = 1;
775 spin_unlock(&dev->spinlock);
776 return 0;
777 }
778
779 void hrt_lock(hrt_t * dev) {
780 unsigned long flags;
781 spin_lock_irqsave(&dev->spinlock, flags);
782 if (dev->is_locked) {
783 HRT_ERROR_MSG("locking an already-locked device");
784 }
785 dev->is_locked = 1;
786 spin_unlock_irqrestore(&dev->spinlock, flags);
787 }
788
789 void hrt_unlock(hrt_t * dev) {
790 spin_lock(&dev->spinlock);
791 if (!dev->is_locked) {
792 HRT_ERROR_MSG("unlocking unlocked device");
793 }
794 dev->is_locked = 0;
795 spin_unlock(&dev->spinlock);
796 }
797
798 int hrt_init(unsigned long phys_address, struct pci_dev * pci_dev)
799 {
800 hrt_t * dev = &hrt_devices[hrt_num_devices];
801 int i, result;
802 char *bus, *color, *ported;
803 unsigned int old_control, old_y_high, old_y_low;
804 unsigned char val1, val2;
805 unsigned long virt_address;
806
807 HRT_DEBUG_MSG(1, "probing device at 0x%lx", phys_address);
808
809 dev = &hrt_devices[hrt_num_devices];
810
811 memset(dev, 0, sizeof(hrt_t));
812 dev->state = HRT_INITIALIZING_STATE;
813 dev->num = hrt_num_devices;
814 hrt_lock_init (dev);
815
816 tasklet_init(&dev->tasklet, hrt_tasklet, (unsigned long) dev);
817
818 /* reserve the I/O address space for this device */
819 if (!request_mem_region(phys_address, HRT_IO_SIZE, "hrt")) {
820 HRT_ERROR_MSG("I/O memory at %lx already in use",
821 (unsigned long) phys_address);
822 return -EBUSY;
823 }
824 dev->phys_addr = phys_address;
825
826 /* map the device's I/O space into kernel memory */
827 virt_address = (unsigned long)
828 ioremap_nocache(phys_address, HRT_IO_SIZE);
829 if (!virt_address) {
830 HRT_ERROR_MSG("couldn't remap io memory!!");
831 hrt_cleanup(dev);
832 return -ENODEV;
833 }
834 dev->virt_addr = virt_address;
835
836 #ifdef CONFIG_PCI
837 /* pci-specific processing */
838 if (pci_dev) {
839 pci_set_drvdata (pci_dev, dev);
840 dev->pci_dev = pci_dev;
841 dev->irq = -pci_dev->irq;
842 dev->mode &= ~HRT_ISA_MODE;
843 /* make certain IRQ is disabled before enabling
844 device, or else we may get an IRQ we are not
845 prepared to handle? */
846 hrt_irq_disable(dev);
847 if (pci_enable_device(pci_dev)) {
848 HRT_ERROR_MSG("pci_enable_device failed");
849 hrt_cleanup(dev);
850 return -EIO;
851 }
852 }
853 #endif
854
855 /* find out whether there is an hrt device at this
856 address, and which type of device it is */
857
858 /* save the values we are about to modify */
859 old_control = ioread8((void *)(HRT_CONTROL_REG + virt_address));
860 old_y_low = ioread8((void *)(HRT_Y_LOW_REG + virt_address));
861 old_y_high = ioread8((void *)(HRT_Y_HIGH_REG + virt_address));
862
863 /* freeze the frame grabbing, immediately */
864 iowrite8(0x5B, (void *) (HRT_CONTROL_REG + virt_address));
865
866 /* complement pixel (0,0) */
867 iowrite16(0, (void *) (HRT_Y_LOW_REG + virt_address));
868 iowrite16(0, (void *) (HRT_Y_HIGH_REG + virt_address));
869 val1 = ioread8((void *) virt_address);
870 iowrite8(~val1, (void *) virt_address);
871
872 /* write old value of pixel (0,0) to (1,0) */
873 iowrite16(1, (void *) (HRT_Y_LOW_REG + virt_address));
874 iowrite8(val1, (void *) virt_address);
875
876 /* read the value at the previous raster/row */
877 iowrite16(0, (void *) (HRT_Y_LOW_REG + virt_address));
878 val2 = ioread8((void *) virt_address);
879
880 if (val2 != (unsigned char)~val1) {
881 HRT_DEBUG_MSG(1, "no hrt device at address 0x%lx",
882 virt_address);
883 /* restore the old values, and hope we did no
884 damage to some other device at this address;
885 this is pretty poor, since if there is
886 another device at that address the effects
887 of these writes could be harmful;
888 ideally, there should be a way to
889 identify the devices that only uses read
890 operations */
891 iowrite8(val1, (void *) virt_address);
892 iowrite8(old_y_low, (void *) (HRT_Y_LOW_REG + virt_address));
893 iowrite8(old_y_high, (void *) (HRT_Y_HIGH_REG + virt_address));
894 iowrite8(old_control, (void *) (HRT_CONTROL_REG + virt_address));
895
896 hrt_cleanup(dev);
897 return -ENODEV;
898 }
899
900 /* test whether we have a color or greyscale card:
901 the color frame buffer has line of 2048 = 0x400
902 pixels; greyscale has only 512 pixels/line, so
903 the memory mapped row of frame buffer memory
904 should wrap around at 0x200 and 0x400 on a greyscale card
905 but should be good through 0x400 on a color card. */
906
907 iowrite8(HRT_FREEZE_IMM_CMD, (void *) (HRT_CONTROL_REG + virt_address));
908 iowrite16(0, (void *) (HRT_Y_LOW_REG + virt_address));
909 iowrite16(0, (void *) (HRT_Y_HIGH_REG + virt_address));
910 val1 = ioread8((void *)(0x400 + virt_address));
911 iowrite8(~val1, (void *) (0x400 + virt_address));
912 /* in case greyscale addresses wrap around,
913 refresh the value at offset zero */
914 iowrite8(val1, (void *) (virt_address));
915 val2 = ioread8((void *)(0x400 + virt_address));
916 if (val2 == (unsigned char) ~val1) {
917 dev->mode |= HRT_COLOR_MODE;
918 /* infer the frame geometry from the device type */
919 HRT_DEBUG_MSG(1, "COLOR device detected");
920 dev->rows = 480;
921 dev->cols = 640;
922 dev->bytes_per_pixel = 2;
923 } else {
924 HRT_DEBUG_MSG(1, "GREYSCALE device detected");
925 dev->cols = 512; /* is for NTSC, 512 for PAL */
926 dev->rows = 480;
927 dev->bytes_per_pixel = 1;
928 }
929
930 /* try to initialize the device */
931 result = hrt_i2c_init_device(dev);
932 if (result) {
933 HRT_ERROR_MSG("hrt_i2c_init_device %d failed",result);
934 hrt_cleanup(dev);
935 return -ENODEV;
936 }
937
938 hrt_go_live(dev); /* delete this once driver is debugged */
939
940 /* find out whether the device has dual-ported memory*/
941
942 /* freeze the image */
943 hrt_freeze_immediate(dev);
944
945 /* write zeros to horizontal raster line 500,
946 a line that the A/D unit does not modify */
947 iowrite16(0, (void *) (dev->virt_addr + HRT_Y_HIGH_REG));
948 iowrite16(500, (void *) (dev->virt_addr + HRT_Y_LOW_REG));
949 for (i = 0; i < 512; i++) {
950 iowrite8(0, (void *)(dev->virt_addr + i));
951 }
952
953 /* set capturing mode */
954 hrt_go_live(dev);
955
956 /* try to overwrite the line with ones */
957 for (i = 0; i < 512; i++) {
958 iowrite8(255, (void *) (dev->virt_addr + i));
959 }
960
961 /* freeze the image */
962 hrt_freeze_immediate(dev);
963
964 /* read back the line;
965 if some of the pixels are still zero the memory is
966 not dual ported */
967 result = 1;
968 for (i = 0; i < 512; i++) {
969 if (!ioread8((void *)(dev->virt_addr + i))) result = 0;
970 }
971 if (result) {
972 HRT_DEBUG_MSG(1, "seems to be dual ported");
973 dev->mode |= HRT_DUAL_PORTED_MODE;
974 }
975
976 dev->mode |= HRT_ISA_MODE;
977
978 #ifdef CONFIG_PCI
979 if ((pci_dev->device == HRT_DEVICE_ID_COLOR) !=
980 ((dev->mode & HRT_COLOR_MODE) == HRT_COLOR_MODE))
981 HRT_ERROR_MSG("PCI and probed types don't match");
982 #endif
983
984 /* discover whether this device supports interrupts */
985 hrt_timer_init(dev);
986 if (dev->mode & HRT_IRQ_MODE) {
987 dev->irq_count = 0;
988 hrt_irq_enable(dev);
989 hrt_go_live(dev);
990 mdelay(20);
991 hrt_freeze_immediate(dev);
992 hrt_irq_disable(dev);
993 if (dev->irq_count) {
994 HRT_DEBUG_MSG(1, "counted %d irqs in 20 ms",
995 dev->irq_count);
996 HRT_ERROR_MSG("devices supports IRQs");
997 } else {
998 HRT_DEBUG_MSG(1, "no irqs in 10 ms");
999 dev->irq = 0;
1000 dev->mode &= ~HRT_IRQ_MODE;
1001 }
1002 }
1003
1004 /* describe this device for the log */
1005 if (dev->mode & HRT_ISA_MODE) bus = "ISA";
1006 else bus = "PCI";
1007 if (dev->mode & HRT_COLOR_MODE) color = "COLOR";
1008 else color = "GREYSCALE";
1009 if (dev->mode & HRT_DUAL_PORTED_MODE) ported = "DUAL";
1010 else ported = "SINGLE";
1011 HRT_ERROR_MSG("found device %d at 0x%lx",
1012 dev->num, dev->phys_addr);
1013 HRT_ERROR_MSG("%s %s with %s-ported memory",
1014 bus, color, ported);
1015 if (dev->mode & HRT_IRQ_MODE)
1016 HRT_ERROR_MSG("using IRQ %d", dev->irq);
1017
1018 init_waitqueue_head(&dev->wait_queue);
1019
1020 /* set default window size
1021 to cover the entire frame buffer */
1022 HRT_DEBUG_MSG(1, "setting width, cols = %d", dev->cols);
1023 dev->win_row = 0;
1024 dev->win_width = dev->cols;
1025 dev->win_col = 0;
1026 dev->win_height = dev->rows;
1027 dev->field = -1;
1028 hrt_num_devices++;
1029 dev->state = HRT_CLOSED_STATE;
1030
1031 return 0;
1032 }
1033
1034 int hrt_isa_init(void)
1035 {
1036 int i;
1037 for (i = 0; i < ARRAY_SIZE(hrt_addresses); i++)
1038 hrt_init(hrt_addresses[i], NULL);
1039 hrt_nonpci_devices = hrt_num_devices;
1040 return 0;
1041 }
1042
1043 void hrt_isa_cleanup(void)
1044 { int i;
1045 for (i=0; i<hrt_nonpci_devices; i++) {
1046 HRT_DEBUG_MSG(2, "cleaning up device %d", i);
1047 hrt_cleanup(hrt_devices+i);
1048 }
1049 }
1050
1051 /*************************
1052 * interrupts and timers *
1053 *************************/
1054
1055 int hrt_irq_pending(hrt_t *dev)
1056 {
1057 int r = ioread8((void *)(dev->virt_addr + HRT_CONTROL_REG)) & 0x4;
1058 rmb();
1059 return r;
1060 }
1061
1062 irqreturn_t hrt_irq_handler(int irq, void* dev_id, struct pt_regs* regs)
1063 {
1064 hrt_t* dev = dev_id;
1065 if (!hrt_irq_pending(dev)) goto none;
1066 /* acknowledge the interrupt */
1067 hrt_irq_disable(dev);
1068 dev->irq_count++;
1069 /* do not try to do any I/O on the device here,
1070 or else risk race with last scheduled tasklet
1071 */
1072 tasklet_schedule(&dev->tasklet);
1073 /* enable the next interrupt */
1074 hrt_irq_enable(dev);
1075 #ifdef IRQ_HANDLED
1076 return IRQ_HANDLED;
1077 #endif
1078 none:
1079 #ifdef IRQ_NONE
1080 return IRQ_NONE;
1081 #endif
1082 }
1083
1084 void hrt_timer_handler(unsigned long data)
1085 {
1086 hrt_t* dev = (hrt_t*)data;
1087
1088 if (dev->timer_active) {
1089 tasklet_schedule(&dev->tasklet);
1090 dev->timer.expires = jiffies + HZ/100;
1091 add_timer(&dev->timer);
1092 }
1093 }
1094
1095 void hrt_irq_init(hrt_t* dev)
1096 {
1097 HRT_DEBUG_MSG(2, "hrt_irq_init");
1098 dev->irq_count = 0;
1099 if (dev->irq == 0) return;
1100 if ((dev->irq > 0) || (dev->mode & HRT_IRQ_MODE)) {
1101 HRT_ERROR_MSG("irq handler already installed");
1102 return;
1103 }
1104 hrt_irq_disable(dev); /* insurance */
1105 if (request_irq(-dev->irq, hrt_irq_handler,
1106 SA_SHIRQ, "hrt", (void*)dev)) {
1107 HRT_ERROR_MSG("unable to reserve IRQ");
1108 dev->irq = 0;
1109 } else {
1110 dev->irq = -dev->irq;
1111 dev->mode |= HRT_IRQ_MODE;
1112 }
1113 }
1114
1115 void hrt_irq_cleanup(hrt_t* dev)
1116 {
1117 HRT_DEBUG_MSG(2, "hrt_irq_cleanup");
1118 if (dev->mode & HRT_IRQ_MODE) {
1119 free_irq(dev->irq, dev);
1120 dev->mode &= ~HRT_IRQ_MODE;
1121 }
1122 }
1123
1124 void hrt_timer_init(hrt_t* dev)
1125 {
1126 HRT_DEBUG_MSG(1, "hrt_timer_init");
1127 HRT_CHECK(dev, HRT_INITIALIZING_STATE, "4");
1128 if (dev->timer_active) {
1129 HRT_ERROR_MSG("irq or timer already active");
1130 }
1131 hrt_irq_init(dev);
1132 if (!(dev->mode & HRT_IRQ_MODE)) {
1133 if (dev->timer.function) {
1134 HRT_ERROR_MSG("timer already initialized");
1135 return;
1136 }
1137 HRT_DEBUG_MSG(1, "installing timer");
1138 init_timer(&dev->timer);
1139 dev->timer.function = hrt_timer_handler;
1140 dev->timer.data = (unsigned long)dev;
1141 }
1142 }
1143
1144 void hrt_timer_cleanup(hrt_t* dev)
1145 {
1146 HRT_DEBUG_MSG(1, "hrt_timer_cleanup");
1147 HRT_CHECK(dev, HRT_FINALIZING_STATE, "3");
1148 hrt_timer_deactivate (dev);
1149 hrt_irq_cleanup(dev);
1150 dev->timer.function = NULL;
1151 }
1152
1153 void hrt_timer_deactivate(hrt_t* dev)
1154 {
1155 HRT_DEBUG_MSG(1, "hrt_timer_deactivate");
1156 if (dev->timer_active) {
1157 dev->timer_active = 0;
1158 if (dev->mode & HRT_IRQ_MODE) hrt_irq_disable(dev);
1159 else del_timer_sync(&dev->timer);
1160 tasklet_disable(&dev->tasklet);
1161 }
1162 }
1163
1164 /* hrt_time_activate
1165 -----------------
1166
1167 starts a task to monitor the state of the device.
1168 This may be driven by a timer or by an interrupt
1169 from the device.
1170 */
1171
1172 int hrt_timer_activate(hrt_t* dev)
1173 {
1174 int result = 0;
1175 HRT_DEBUG_MSG(1, "hrt_timer_activate");
1176 if (dev->timer_active) {
1177 HRT_ERROR_MSG("irq or timer already active");
1178 return 0;
1179 }
1180 dev->timer_active = 1;
1181 if (dev->mode & HRT_IRQ_MODE) {
1182 HRT_DEBUG_MSG(1, "enabling irq");
1183 hrt_irq_enable(dev);
1184 } else {
1185 if (!dev->timer.function) {
1186 HRT_ERROR_MSG("timer not initialized");
1187 return -1;
1188 }
1189 dev->timer.expires = jiffies + HZ/100;
1190 add_timer(&dev->timer);
1191 }
1192 return result;
1193 }
1194
1195 /* hrt_tasklet
1196 -----------
1197
1198 is called in response to either a timer interrupt
1199 or an interrupt generated by the device
1200
1201 */
1202
1203 void hrt_tasklet(unsigned long data)
1204 { int field;
1205 hrt_t *dev = (hrt_t *) data;
1206 if (hrt_trylock (dev)) { /* device is busy */
1207 /* could add a wakeup mechanism here */
1208 return;
1209 }
1210 field = hrt_get_field (dev);
1211 if (dev->field == -1) {
1212 /* just started; don't know previous state */
1213 dev->field = field;
1214 goto done;
1215 }
1216 if (field != dev->field) {
1217 /* field has changed */
1218 if (dev->field_changes == 1) {
1219 HRT_DEBUG_MSG(1, "field changes going to 0 %d", dev->num);
1220 wake_up_interruptible (&dev->wait_queue);
1221 }
1222 if (dev->field_changes) dev->field_changes--;
1223 }
1224 /* .... this code is incomplete
1225 Eventually, there should be code here to
1226 keep track of how many fields have been digitized,
1227 and arrange for buffering the data */
1228 done:
1229 hrt_unlock(dev);
1230 }
1231
1232 /********************************
1233 * basic file operations (fops) *
1234 ********************************/
1235
1236 int hrt_open (struct inode *inode, struct file *file);
1237 int hrt_release(struct inode *inode, struct file *file);
1238 int hrt_read (struct file *file, char *buf, size_t count, loff_t * ppos);
1239 int hrt_ioctl (struct inode *inode, struct file *filp,
1240 unsigned int cmd, unsigned long arg);
1241 int hrt_mmap (struct file *file, struct vm_area_struct *vma);
1242
1243 static struct file_operations hrt_fops = {
1244 .owner = THIS_MODULE,
1245 .open = hrt_open,
1246 .release = hrt_release,
1247 .read = hrt_read,
1248 .ioctl = hrt_ioctl,
1249 .mmap = hrt_mmap,
1250 };
1251
1252 /**
1253 * hrt_open
1254 *
1255 * checks minor number range, sets private_data,
1256 * starts timer if necessary, increments users
1257 */
1258 int hrt_open(struct inode *inode, struct file *file)
1259 {
1260 hrt_t* dev;
1261 unsigned int minor;
1262 int result = 0;
1263
1264 minor = MINOR(inode->i_rdev);
1265 if (minor >= HRT_MAX_DEVICES) return -ENODEV;
1266
1267 dev = hrt_devices + minor;
1268 HRT_DEBUG_MSG(1, "opening device %d at addr %lX", minor, (unsigned long)dev);
1269
1270 if (dev->state != HRT_CLOSED_STATE) {
1271 HRT_DEBUG_MSG(2, "already open");
1272 return -EBUSY;
1273 }
1274 HRT_DEBUG_MSG(2, "setting private data");
1275 file->private_data = (void*)dev;
1276 dev->state = HRT_OPEN_STATE;
1277 hrt_go_live(dev);
1278
1279 /* FIXME: shift responsibility for buffer allocation
1280 to open (here) and deallocation to the release operation;
1281 only do this later, when everything else is working. */
1282
1283 HRT_DEBUG_MSG(2, "installing timer/irq");
1284 result = hrt_timer_activate(dev);
1285
1286 return result;
1287 }
1288
1289 /* hrt_release should not need any lock, because
1290 it is only called by the system, on last close; at that
1291 point there should be no possibility of more calls that
1292 touch this device, unless they are from a timer
1293 or interrrupt handler */
1294
1295 int hrt_release(struct inode *inode, struct file *file)
1296 {
1297 hrt_t* dev = file->private_data;
1298 if (dev->state != HRT_OPEN_STATE) return -ENODEV;
1299 dev->state = HRT_CLOSED_STATE;
1300 hrt_timer_deactivate(dev);
1301 /* above should wait for active tasklet to finish */
1302 return 0;
1303 }
1304
1305 int hrt_read(struct file *file, char *buf, size_t count, loff_t * ppos)
1306 {
1307 hrt_t* dev = file->private_data;
1308 int max_count, result;
1309
1310 HRT_DEBUG_MSG(3, "hrt_read_proc (1) count = %d", count);
1311 if (dev->state != HRT_OPEN_STATE) return -ENODEV;
1312
1313 hrt_lock(dev);
1314 dev->field_changes = 2;
1315 if (dev->is_frozen) {
1316 hrt_go_live (dev);
1317 hrt_unlock(dev);
1318 if (wait_event_interruptible(dev->wait_queue, dev->field_changes == 0)) {
1319 return -ERESTARTSYS;
1320 }
1321 hrt_lock(dev);
1322 dev->field_changes = 2;
1323 }
1324
1325 hrt_freeze_next(dev);
1326 hrt_unlock(dev);
1327 if (wait_event_interruptible(dev->wait_queue, dev->field_changes == 0)) {
1328 return -ERESTARTSYS;
1329 }
1330
1331 HRT_DEBUG_MSG(3, "hrt_read_proc (3) bpp = %d width = %d height = %d",
1332 dev->bytes_per_pixel, dev->win_width, dev->win_height);
1333 max_count = dev->win_width * dev->win_height * dev->bytes_per_pixel;
1334 if (count > max_count) count = max_count;
1335 hrt_lock(dev);
1336 HRT_DEBUG_MSG(3, "hrt_read_proc (4) count = %d", count);
1337 if ((result = hrt_copy_window(dev, buf))) {
1338 HRT_DEBUG_MSG(3, "hrt_copy_window failed %d", result);
1339 hrt_unlock(dev);
1340 return -EFAULT;
1341 }
1342 hrt_unlock(dev);
1343 HRT_DEBUG_MSG(3, "hrt_read_proc (5)");
1344 return count;
1345 }
1346
1347 /*
1348 * ioctl operations
1349 */
1350
1351 int hrt_ioctl(struct inode *inode, struct file *file,
1352 unsigned int cmd, unsigned long arg)
1353 {
1354 int result = 0, iarg = *((int*)arg);
1355 hrt_t* dev = file->private_data;
1356
1357
1358 switch (cmd)
1359 {
1360 case IOC_HRT_FREEZE_FRAME:
1361 HRT_DEBUG_MSG(2, "IOC_HRT_FREEZE_FRAME: called");
1362 hrt_freeze_next(dev);
1363 break;
1364
1365 case IOC_HRT_GO_LIVE:
1366 HRT_DEBUG_MSG(2, "IOC_HRT_GO_LIVE: called");
1367 hrt_go_live(dev);
1368 break;
1369
1370 case IOC_HRT_WIN_SET_WIDTH:
1371 HRT_DEBUG_MSG(2, "IOC_HRT_WIN_SET_WIDTH: called with arg %d", iarg);
1372 dev->win_width = iarg;
1373 break;
1374 case IOC_HRT_WIN_SET_HEIGHT:
1375 HRT_DEBUG_MSG(2, "IOC_HRT_WIN_SET_HEIGHT: called with arg %d", iarg);
1376 dev->win_height = iarg;
1377 break;
1378 case IOC_HRT_WIN_SET_X:
1379 HRT_DEBUG_MSG(2, "IOC_HRT_WIN_SET_X: called with arg %d", iarg);
1380 dev->win_col = iarg;
1381 break;
1382 case IOC_HRT_WIN_SET_Y:
1383 HRT_DEBUG_MSG(2, "IOC_HRT_WIN_SET_Y: called with arg %d", iarg);
1384 dev->win_row = iarg;
1385 break;
1386
1387 default:
1388 result = -ENOSYS;
1389 break;
1390 }
1391
1392 return result;
1393 }
1394
1395 int hrt_mmap (struct file *file, struct vm_area_struct *vma)
1396 {
1397 return -ENOSYS;
1398 }
1399
1400 #ifdef CONFIG_PCI
1401
1402 /***************
1403 * PCI support *
1404 ***************/
1405
1406 MODULE_DEVICE_TABLE(pci, hrt_pci_tbl);
1407 int hrt_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id);
1408 void hrt_pci_remove (struct pci_dev *pci_dev);
1409
1410 static struct pci_device_id hrt_pci_tbl[] __devinitdata = {
1411 {PCI_DEVICE(HRT_VENDOR_ID, HRT_DEVICE_ID_GREY)},
1412 {PCI_DEVICE(HRT_VENDOR_ID, HRT_DEVICE_ID_COLOR)},
1413 {0,}
1414 };
1415
1416 static struct pci_driver hrt_pci_driver = {
1417 .name = "hrt",
1418 .id_table = hrt_pci_tbl,
1419 .probe = hrt_pci_probe,
1420 .remove = __devexit_p(hrt_pci_remove)
1421 };
1422
1423 int hrt_pci_probe(struct pci_dev *pci_dev,
1424 const struct pci_device_id *pci_id)
1425 {
1426 HRT_DEBUG_MSG(2, "probing pci device");
1427
1428 /* check that this is a type of device we support */
1429 if ((pci_dev->device != HRT_DEVICE_ID_COLOR) &&
1430 (pci_dev->device != HRT_DEVICE_ID_GREY)) {
1431 HRT_ERROR_MSG("unknown device type 0x%hx",
1432 pci_dev->device);
1433 return -ENODEV;
1434 }
1435
1436 if (hrt_num_devices >= HRT_MAX_DEVICES) {
1437 HRT_ERROR_MSG("need to increase HRT_MAX_DEVICES");
1438 return -ENOMEM;
1439 }
1440
1441 return hrt_init(pci_resource_start(pci_dev, 0), pci_dev);
1442 }
1443
1444 /* since these cards are not intended to be hot-pluggable,
1445 we do not try to reuse hrt_t objects; we just use the remove
1446 operation for removal of the device driver module */
1447
1448 void hrt_pci_remove (struct pci_dev *pci_dev)
1449 {
1450 hrt_t *dev;
1451 HRT_DEBUG_MSG(2, "hrt_pci_remove");
1452 dev = (hrt_t *) pci_get_drvdata (pci_dev);
1453 hrt_cleanup(dev);
1454 pci_disable_device(pci_dev);
1455 }
1456
1457 void hrt_pci_init(void)
1458 {
1459 HRT_DEBUG_MSG(2, "pci_register_driver");
1460 pci_register_driver(&hrt_pci_driver);
1461 }
1462
1463 void hrt_pci_cleanup(void)
1464 {
1465 HRT_DEBUG_MSG(2, "pci_unregister_driver");
1466 pci_unregister_driver(&hrt_pci_driver);
1467 }
1468
1469 #else
1470
1471 /* no PCI support */
1472
1473 void hrt_pci_init(void)
1474 {
1475 }
1476
1477 void hrt_pci_cleanup(void)
1478 {
1479 }
1480
1481 #endif
1482
1483 /*************************************
1484 * module initialization and cleanup *
1485 *************************************/
1486
1487 int hrt_major_number = 0;
1488
1489 void hrt_cleanup_module(void)
1490 {
1491 HRT_MODULE_CHECK (HRT_MODULE_INITIALIZING_STATE |
1492 HRT_MODULE_INITIALIZED_STATE, "6");
1493 hrt_module_state = HRT_MODULE_FINALIZING_STATE;
1494 HRT_DEBUG_MSG(2, "hrt_cleanup_module");
1495 hrt_isa_cleanup();
1496 hrt_pci_cleanup();
1497 if (hrt_major_number) unregister_chrdev(hrt_major_number, "hrt");
1498 hrt_debug_cleanup();
1499 hrt_module_state = HRT_MODULE_UNINITIALIZED_STATE;
1500 }
1501
1502 int hrt_init_module(void)
1503 {
1504 int result = 0;
1505 hrt_module_state = HRT_MODULE_INITIALIZING_STATE;
1506 hrt_debug_init();
1507 result = register_chrdev(major_number, "hrt", &hrt_fops);
1508 if (result < 0) {
1509 HRT_ERROR_MSG("failed to register char device %d",
1510 major_number);
1511 goto failed;
1512 }
1513
1514 /* use major number returned by system if no
1515 major number is specified by this module */
1516 if (major_number == 0) hrt_major_number = result;
1517 else hrt_major_number = major_number;
1518 HRT_ERROR_MSG("module initializing with major number %d",
1519 hrt_major_number);
1520
1521 memset(hrt_devices, 0, sizeof(hrt_devices));
1522
1523 /* detect ISA/PC104 devices, and PCI devices that are
1524 jumpered to use the ISA/PC104 I/O address space */
1525 hrt_isa_init();
1526
1527 /* now detect regular PCI devices */
1528 hrt_pci_init();
1529
1530 if (hrt_num_devices == 0) {
1531 HRT_ERROR_MSG("no hrt devices detected");
1532 hrt_module_state = HRT_MODULE_UNINITIALIZED_STATE;
1533 return -ENODEV;
1534 } else {
1535 HRT_ERROR_MSG("found %d hrt devices", hrt_num_devices);
1536 }
1537 hrt_module_state = HRT_MODULE_INITIALIZED_STATE;
1538 return 0;
1539 failed:
1540 hrt_cleanup_module();
1541 HRT_DEBUG_MSG(2, "returning from failed init_module() with result %d",
1542 result);
1543 hrt_module_state = HRT_MODULE_UNINITIALIZED_STATE;
1544 return result;
1545 }
1546
1547 module_init(hrt_init_module);
1548 module_exit(hrt_cleanup_module);
1549
1550 MODULE_LICENSE("GPL");
1551
|
This page was automatically generated by the
LXR engine.
|