Mercurial > mplayer.hg
annotate drivers/sis_vid.c @ 4218:3931c41f740a
Added new syncengine thanks to a new previously undocumented feature of the em8300, this might fix playback on both slow and fast machines (more testing needed). This also requires users to get the em8300 driver from cvs until the next version is released (will probably happen this weekend)
Added lots of comments, should be pretty easy to understand most of the internals now
Added lots of brackets to if's for's while's etc, this is not a cosmetical thing but rather due to the fact I got some very odd bugs with else's since I didn't properly use brackets (and it's the K&R standard to have brackets everywhere)
Fixed some bugs that would occur when disabling libmp1e
Switched to default to the new naming scheme of device nodes, the driver will slowly switch over to this state, if it can't find devices under the new name it will try the old naming scheme
I stopped opening devices in non-blocking mode, it would break the new syncengine which tries to burst data to the device (alot of times meaning it will fill the fifo pretty fast which would previously result in jerkyness on fast machines)
The device now sets the initial state of the pts and speed (probably not needed, but assumption is the mother of all fuckups =)
Keep the control interface open during the entire duration of the libvo device, we might need this to flush video buffers on seeking (currently not implemented, therefore seeking is broken)
This is beta stuff to the driver, I will get some users to test it for me and do my best to fix seeking as soon as possible...
author | mswitch |
---|---|
date | Thu, 17 Jan 2002 10:33:47 +0000 |
parents | d62aa0b7fd68 |
children |
rev | line source |
---|---|
1 | 1 /* |
2 * | |
3 * sis_vid.c | |
4 * | |
5 * Copyright (C) 2000 Aaron Holtzman | |
6 * | |
7 * This software has been released under the terms of the GNU Public | |
8 * license. See http://www.gnu.org/copyleft/gpl.html for details. | |
9 */ | |
10 | |
11 // video4linux interface disabled by A'rpi/ESP-team | |
12 | |
13 | |
14 //It's entirely possible this major conflicts with something else | |
15 /* mknod /dev/mga_vid c 178 0 */ | |
16 | |
17 #include <linux/config.h> | |
18 #include <linux/version.h> | |
19 #include <linux/module.h> | |
20 #include <linux/types.h> | |
21 #include <linux/kernel.h> | |
22 #include <linux/sched.h> | |
23 #include <linux/mm.h> | |
24 #include <linux/string.h> | |
25 #include <linux/errno.h> | |
3125
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
62
diff
changeset
|
26 |
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
62
diff
changeset
|
27 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) |
1 | 28 #include <linux/malloc.h> |
3125
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
62
diff
changeset
|
29 #else |
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
62
diff
changeset
|
30 #include <linux/slab.h> |
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
62
diff
changeset
|
31 #endif |
d62aa0b7fd68
use <linux/slab.h> instead of <linux/malloc.h> for kernels 2.4.9+
szabi
parents:
62
diff
changeset
|
32 |
1 | 33 #include <linux/pci.h> |
34 #include <linux/init.h> | |
35 //#include <linux/videodev.h> | |
36 | |
37 #include "sis_vid.h" | |
38 | |
39 #ifdef CONFIG_MTRR | |
40 #include <asm/mtrr.h> | |
41 #endif | |
42 | |
43 #include <asm/uaccess.h> | |
44 #include <asm/system.h> | |
45 #include <asm/io.h> | |
46 | |
47 #define TRUE 1 | |
48 #define FALSE 0 | |
49 | |
50 #define MGA_VID_MAJOR 178 | |
51 | |
52 | |
53 #ifndef PCI_DEVICE_ID_SI_6323 | |
54 #define PCI_DEVICE_ID_SI_6323 0x6326 | |
55 #endif | |
56 | |
57 | |
58 MODULE_AUTHOR("Aaron Holtzman <aholtzma@engr.uvic.ca>"); | |
59 | |
60 | |
61 typedef struct bes_registers_s | |
62 { | |
63 //base address of yuv framebuffer | |
64 uint32_t yuv_base; | |
65 uint32_t u_base; | |
66 uint32_t v_base; | |
67 uint32_t fb_end;; | |
68 | |
69 //frame buffer pitch | |
70 uint32_t pitch; | |
71 | |
72 //window boundaries | |
73 uint32_t left; | |
74 uint32_t right; | |
75 uint32_t top; | |
76 uint32_t bottom; | |
77 | |
78 //control registers | |
79 uint32_t misc_0; | |
80 uint32_t misc_1; | |
81 uint32_t misc_3; | |
82 uint32_t misc_4; | |
83 | |
84 //key overlay mode | |
85 uint32_t key_mode; | |
86 | |
87 } bes_registers_t; | |
88 | |
89 static bes_registers_t regs; | |
90 static uint32_t mga_vid_in_use = 0; | |
91 static uint32_t vid_src_ready = 0; | |
92 static uint32_t vid_overlay_on = 0; | |
93 | |
94 static uint8_t *mga_mmio_base = 0; | |
95 static uint32_t mga_mem_base = 0; | |
96 static uint32_t mga_src_base = 0; | |
97 | |
98 static uint32_t mga_ram_size = 0; | |
99 | |
100 static struct pci_dev *pci_dev; | |
101 | |
102 //static struct video_window mga_win; | |
103 static mga_vid_config_t mga_config; | |
104 | |
105 | |
106 | |
107 // Backend Scaler registers | |
108 | |
109 #define MISC_0 0x98 | |
110 #define MISC_1 0x99 | |
111 #define MISC_3 0x9d | |
112 #define MISC_4 0xb6 | |
113 | |
114 | |
115 | |
116 | |
117 static void mga_vid_frame_sel(int frame) | |
118 { | |
119 //we don't need the vcount protection as we're only hitting | |
120 //one register (and it doesn't seem to be double buffered) | |
121 //regs.besctl = (regs.besctl & ~0x07000000) + (frame << 25); | |
122 //writel( regs.besctl, mga_mmio_base + BESCTL ); | |
123 } | |
124 | |
125 | |
126 #define WRITE_REG(x,y,z) {outb((y),(x));outb((z),(x+1));} | |
127 #define READ_REG(x,y) (outb((y),(x)),inb(x+1)) | |
128 #define VIDEO_ACCEL 0x3d4 | |
129 | |
130 static void mga_vid_write_regs(void) | |
131 { | |
132 uint32_t foo; | |
133 | |
134 //unlock the video accel registers | |
135 WRITE_REG(VIDEO_ACCEL,0x80,0x86); | |
136 foo = READ_REG(VIDEO_ACCEL,0x80); | |
137 | |
138 if(foo != 0xa1) | |
139 return; //something bad happened | |
140 | |
141 //setup the horizontal window bounds | |
142 WRITE_REG(VIDEO_ACCEL,0x81,regs.left & 0xff); | |
143 WRITE_REG(VIDEO_ACCEL,0x82,regs.right & 0xff); | |
144 WRITE_REG(VIDEO_ACCEL,0x83,(regs.left >> 8) | ((regs.right>>4) & 0x70)); | |
145 | |
146 //setup the vertical window bounds | |
147 WRITE_REG(VIDEO_ACCEL,0x84,regs.top & 0xff); | |
148 WRITE_REG(VIDEO_ACCEL,0x85,regs.bottom & 0xff); | |
149 WRITE_REG(VIDEO_ACCEL,0x86,(regs.top >> 8) | ((regs.bottom>>4) & 0x70)); | |
150 | |
151 //setup the framebuffer base addresses | |
152 WRITE_REG(VIDEO_ACCEL,0x8a,regs.yuv_base & 0xff); | |
153 WRITE_REG(VIDEO_ACCEL,0x8b,(regs.yuv_base >> 8) & 0xff); | |
154 WRITE_REG(VIDEO_ACCEL,0x89,(regs.yuv_base >> 12) & 0xf0); | |
155 | |
156 WRITE_REG(VIDEO_ACCEL,0xb7,regs.u_base & 0xff); | |
157 WRITE_REG(VIDEO_ACCEL,0xb8,(regs.u_base >> 8) & 0xff); | |
158 | |
159 WRITE_REG(VIDEO_ACCEL,0xba,regs.v_base & 0xff); | |
160 WRITE_REG(VIDEO_ACCEL,0xbb,(regs.v_base >> 8) & 0xff); | |
161 WRITE_REG(VIDEO_ACCEL,0xb9,((regs.v_base >> 12) & 0xf0) + ((regs.u_base >> 16) & 0xf)); | |
162 | |
163 WRITE_REG(VIDEO_ACCEL,0x8d,regs.fb_end); | |
164 | |
165 //setup framebuffer pitch | |
166 WRITE_REG(VIDEO_ACCEL,0x8c,regs.pitch & 0xff); | |
167 WRITE_REG(VIDEO_ACCEL,0x8e,(regs.pitch >> 8) & 0x0f); | |
168 WRITE_REG(VIDEO_ACCEL,0xbc,(regs.pitch) & 0xff); | |
169 WRITE_REG(VIDEO_ACCEL,0xbd,((regs.pitch) >> 8) & 0x0f); | |
170 | |
171 | |
172 //write key overlay register | |
173 WRITE_REG(VIDEO_ACCEL,0xa9,regs.key_mode); | |
174 | |
175 WRITE_REG(VIDEO_ACCEL,0x93,0x40); | |
176 WRITE_REG(VIDEO_ACCEL,0x94,1); | |
177 WRITE_REG(VIDEO_ACCEL,0x9e,0); | |
178 WRITE_REG(VIDEO_ACCEL,0x9f,0); | |
179 | |
180 //write config registers | |
181 WRITE_REG(VIDEO_ACCEL,MISC_0,regs.misc_0); | |
182 WRITE_REG(VIDEO_ACCEL,MISC_1,regs.misc_1); | |
183 WRITE_REG(VIDEO_ACCEL,MISC_3,regs.misc_3); | |
184 WRITE_REG(VIDEO_ACCEL,MISC_4,regs.misc_4); | |
185 | |
186 //setup the video line buffer | |
187 WRITE_REG(VIDEO_ACCEL,0xa0,(regs.right - regs.left)/ 8); | |
188 | |
189 } | |
190 | |
191 static int mga_vid_set_config(mga_vid_config_t *config) | |
192 { | |
193 uint32_t x, y, frame_size; | |
194 | |
195 x = config->x_org; | |
196 y = config->y_org; | |
197 | |
198 regs.left = x; | |
199 regs.right= config->src_width + x; | |
200 regs.top = y; | |
201 regs.bottom = config->src_height + y; | |
202 | |
62 | 203 printk(KERN_DEBUG "mga_vid: Setting up a %dx%d+%d+%d video window (src %dx%d)\n", |
1 | 204 config->dest_width, config->dest_height, config->x_org, config->y_org, |
205 config->src_width, config->src_height); | |
206 | |
207 | |
208 regs.pitch = ((config->src_width + 31) & ~31) / 4 ; | |
209 | |
210 //frame size in pixels | |
211 frame_size = regs.pitch * config->src_height * 4; | |
212 | |
213 regs.yuv_base = (mga_src_base) >> 2; | |
214 regs.u_base = (mga_src_base + frame_size) >> 2; | |
215 regs.v_base = (mga_src_base + frame_size/4) >> 2; | |
216 regs.fb_end = (mga_src_base + (3*frame_size)/2) >> 14; | |
217 | |
218 //disable video capture, enable video display, enable graphics display, | |
219 //select yuv format, odd parity | |
220 regs.misc_0 = (1 << 1) + (1<<6) + (1<<4); | |
221 | |
222 //disable dithering, no filtering, no interrupts | |
223 regs.misc_1 = 0; | |
224 | |
225 //select 2's complement format YUV for playback | |
226 regs.misc_3 = (1<<1); | |
227 | |
228 //select 4:2:0 video format, + yuv4:2:2 cpu writes | |
229 regs.misc_4 = (1<<2); | |
230 | |
231 //disable keying | |
232 regs.key_mode = 0xf; | |
233 | |
234 mga_vid_write_regs(); | |
235 return 0; | |
236 } | |
237 | |
238 | |
239 static int mga_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | |
240 { | |
241 int frame; | |
242 | |
243 switch(cmd) | |
244 { | |
245 case MGA_VID_CONFIG: | |
246 //FIXME remove | |
62 | 247 printk(KERN_DEBUG "mga_mmio_base = %p\n",mga_mmio_base); |
248 printk(KERN_DEBUG "mga_mem_base = %08x\n",mga_mem_base); | |
1 | 249 //FIXME remove |
250 | |
62 | 251 printk(KERN_DEBUG "mga_vid: Received configuration\n"); |
1 | 252 |
253 if(copy_from_user(&mga_config,(mga_vid_config_t*) arg,sizeof(mga_vid_config_t))) | |
254 { | |
62 | 255 printk(KERN_ERR "mga_vid: failed copy from userspace\n"); |
1 | 256 return(-EFAULT); |
257 } | |
258 | |
259 mga_config.ram_size = mga_ram_size; | |
260 //XXX make it look like a g400 | |
261 mga_config.card_type = MGA_G400;; | |
262 | |
263 if (copy_to_user((mga_vid_config_t *) arg, &mga_config, sizeof(mga_vid_config_t))) | |
264 { | |
62 | 265 printk(KERN_ERR "mga_vid: failed copy to userspace\n"); |
1 | 266 return(-EFAULT); |
267 } | |
268 return mga_vid_set_config(&mga_config); | |
269 break; | |
270 | |
271 case MGA_VID_ON: | |
62 | 272 printk(KERN_DEBUG "mga_vid: Video ON\n"); |
1 | 273 vid_src_ready = 1; |
274 if(vid_overlay_on) | |
275 { | |
276 //regs.besctl |= 1; | |
277 mga_vid_write_regs(); | |
278 } | |
279 break; | |
280 | |
281 case MGA_VID_OFF: | |
62 | 282 printk(KERN_DEBUG "mga_vid: Video OFF\n"); |
1 | 283 vid_src_ready = 0; |
284 //regs.besctl &= ~1; | |
285 mga_vid_write_regs(); | |
286 break; | |
287 | |
288 case MGA_VID_FSEL: | |
289 if(copy_from_user(&frame,(int *) arg,sizeof(int))) | |
290 { | |
62 | 291 printk(KERN_ERR "mga_vid: FSEL failed copy from userspace\n"); |
1 | 292 return(-EFAULT); |
293 } | |
294 | |
295 mga_vid_frame_sel(frame); | |
296 break; | |
297 | |
298 default: | |
62 | 299 printk(KERN_ERR "mga_vid: Invalid ioctl\n"); |
1 | 300 return (-EINVAL); |
301 } | |
302 | |
303 return 0; | |
304 } | |
305 | |
306 | |
307 static int mga_vid_find_card(void) | |
308 { | |
309 struct pci_dev *dev = NULL; | |
310 | |
311 if((dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_6323, NULL))) | |
312 { | |
62 | 313 printk(KERN_DEBUG "sis_vid: Found SiS 6326\n"); |
1 | 314 } |
315 else | |
316 { | |
62 | 317 printk(KERN_ERR "sis_vid: No supported cards found\n"); |
1 | 318 return FALSE; |
319 } | |
320 | |
321 pci_dev = dev; | |
322 | |
323 #if LINUX_VERSION_CODE >= 0x020300 | |
324 mga_mmio_base = ioremap_nocache(dev->resource[1].start,0x10000); | |
325 mga_mem_base = dev->resource[0].start; | |
326 #else | |
327 mga_mmio_base = ioremap_nocache(dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK,0x10000); | |
328 mga_mem_base = dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK; | |
329 #endif | |
62 | 330 printk(KERN_DEBUG "mga_vid: MMIO at 0x%p\n", mga_mmio_base); |
331 printk(KERN_DEBUG "mga_vid: Frame Buffer at 0x%08x\n", mga_mem_base); | |
1 | 332 |
333 //FIXME set ram size properly | |
334 mga_ram_size = 4; | |
335 mga_src_base = (mga_ram_size - 1) * 0x100000; | |
336 | |
337 //FIXME remove | |
338 if(1) | |
339 { | |
340 mga_vid_config_t config ={0,0,256,256,256,256,10,10,0,0,0,0}; | |
341 | |
342 mga_vid_set_config(&config); | |
343 mga_vid_write_regs(); | |
344 //regs.misc_0 ^= 2; | |
345 //mga_vid_write_regs(); | |
346 } | |
347 //FIXME remove | |
348 | |
349 return TRUE; | |
350 } | |
351 | |
352 | |
353 static ssize_t mga_vid_read(struct file *file, char *buf, size_t count, loff_t *ppos) | |
354 { | |
355 return -EINVAL; | |
356 } | |
357 | |
358 static ssize_t mga_vid_write(struct file *file, const char *buf, size_t count, loff_t *ppos) | |
359 { | |
360 return -EINVAL; | |
361 } | |
362 | |
363 static int mga_vid_mmap(struct file *file, struct vm_area_struct *vma) | |
364 { | |
365 | |
62 | 366 printk(KERN_DEBUG "mga_vid: mapping video memory into userspace\n"); |
1 | 367 if(remap_page_range(vma->vm_start, mga_mem_base + mga_src_base, |
368 vma->vm_end - vma->vm_start, vma->vm_page_prot)) | |
369 { | |
62 | 370 printk(KERN_ERR "mga_vid: error mapping video memory\n"); |
1 | 371 return(-EAGAIN); |
372 } | |
373 | |
374 return(0); | |
375 } | |
376 | |
377 static int mga_vid_release(struct inode *inode, struct file *file) | |
378 { | |
379 //Close the window just in case | |
380 vid_src_ready = 0; | |
381 regs.misc_0 &= 0xed; | |
382 mga_vid_write_regs(); | |
383 mga_vid_in_use = 0; | |
384 | |
385 //FIXME put back in! | |
386 //MOD_DEC_USE_COUNT; | |
387 return 0; | |
388 } | |
389 | |
390 static long long mga_vid_lseek(struct file *file, long long offset, int origin) | |
391 { | |
392 return -ESPIPE; | |
393 } | |
394 | |
395 static int mga_vid_open(struct inode *inode, struct file *file) | |
396 { | |
397 int minor = MINOR(inode->i_rdev); | |
398 | |
399 if(minor != 0) | |
400 return(-ENXIO); | |
401 | |
402 if(mga_vid_in_use == 1) | |
403 return(-EBUSY); | |
404 | |
405 mga_vid_in_use = 1; | |
406 //FIXME turn me back on! | |
407 //MOD_INC_USE_COUNT; | |
408 return(0); | |
409 } | |
410 | |
411 #if LINUX_VERSION_CODE >= 0x020400 | |
412 static struct file_operations mga_vid_fops = | |
413 { | |
414 llseek: mga_vid_lseek, | |
415 read: mga_vid_read, | |
416 write: mga_vid_write, | |
417 ioctl: mga_vid_ioctl, | |
418 mmap: mga_vid_mmap, | |
419 open: mga_vid_open, | |
420 release: mga_vid_release | |
421 }; | |
422 #else | |
423 static struct file_operations mga_vid_fops = | |
424 { | |
425 mga_vid_lseek, | |
426 mga_vid_read, | |
427 mga_vid_write, | |
428 NULL, | |
429 NULL, | |
430 mga_vid_ioctl, | |
431 mga_vid_mmap, | |
432 mga_vid_open, | |
433 NULL, | |
434 mga_vid_release | |
435 }; | |
436 #endif | |
437 | |
438 #if 0 | |
439 static long mga_v4l_read(struct video_device *v, char *buf, unsigned long count, | |
440 int noblock) | |
441 { | |
442 return -EINVAL; | |
443 } | |
444 | |
445 static long mga_v4l_write(struct video_device *v, const char *buf, unsigned long count, int noblock) | |
446 { | |
447 return -EINVAL; | |
448 } | |
449 | |
450 static int mga_v4l_open(struct video_device *dev, int mode) | |
451 { | |
452 MOD_INC_USE_COUNT; | |
453 return 0; | |
454 } | |
455 | |
456 static void mga_v4l_close(struct video_device *dev) | |
457 { | |
458 //regs.besctl &= ~1; | |
459 mga_vid_write_regs(); | |
460 vid_overlay_on = 0; | |
461 MOD_DEC_USE_COUNT; | |
462 return; | |
463 } | |
464 | |
465 static int mga_v4l_init_done(struct video_device *dev) | |
466 { | |
467 return 0; | |
468 } | |
469 | |
470 static int mga_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *arg) | |
471 { | |
472 switch(cmd) | |
473 { | |
474 case VIDIOCGCAP: | |
475 { | |
476 struct video_capability b; | |
477 strcpy(b.name, "Matrox G200/400"); | |
478 b.type = VID_TYPE_SCALES|VID_TYPE_OVERLAY|VID_TYPE_CHROMAKEY; | |
479 b.channels = 0; | |
480 b.audios = 0; | |
481 b.maxwidth = 1024; /* GUESS ?? */ | |
482 b.maxheight = 768; | |
483 b.minwidth = 32; | |
484 b.minheight = 16; /* GUESS ?? */ | |
485 if(copy_to_user(arg,&b,sizeof(b))) | |
486 return -EFAULT; | |
487 return 0; | |
488 } | |
489 case VIDIOCGPICT: | |
490 { | |
491 /* | |
492 * Default values.. if we can change this we | |
493 * can add the feature later | |
494 */ | |
495 struct video_picture vp; | |
496 vp.brightness = 0x8000; | |
497 vp.hue = 0x8000; | |
498 vp.colour = 0x8000; | |
499 vp.whiteness = 0x8000; | |
500 vp.depth = 8; | |
501 /* Format is a guess */ | |
502 vp.palette = VIDEO_PALETTE_YUV420P; | |
503 if(copy_to_user(arg, &vp, sizeof(vp))) | |
504 return -EFAULT; | |
505 return 0; | |
506 } | |
507 case VIDIOCSPICT: | |
508 { | |
509 return -EINVAL; | |
510 } | |
511 case VIDIOCSWIN: | |
512 { | |
513 struct video_window vw; | |
514 if(copy_from_user(&vw, arg, sizeof(vw))) | |
515 return -EFAULT; | |
516 if(vw.x <0 || vw.y <0 || vw.width < 32 | |
517 || vw.height < 16) | |
518 return -EINVAL; | |
519 memcpy(&mga_win, &vw, sizeof(mga_win)); | |
520 | |
521 mga_config.x_org = vw.x; | |
522 mga_config.y_org = vw.y; | |
523 mga_config.dest_width = vw.width; | |
524 mga_config.dest_height = vw.height; | |
525 | |
526 /* | |
527 * May have to add | |
528 * | |
529 * #define VIDEO_WINDOW_CHROMAKEY 16 | |
530 * | |
531 * to <linux/videodev.h> | |
532 */ | |
533 | |
534 //add it here for now | |
535 #define VIDEO_WINDOW_CHROMAKEY 16 | |
536 | |
537 if (vw.flags & VIDEO_WINDOW_CHROMAKEY) | |
538 mga_config.colkey_on = 1; | |
539 else | |
540 mga_config.colkey_on = 0; | |
541 | |
542 mga_config.colkey_red = (vw.chromakey >> 24) & 0xFF; | |
543 mga_config.colkey_green = (vw.chromakey >> 16) & 0xFF; | |
544 mga_config.colkey_blue = (vw.chromakey >> 8) & 0xFF; | |
545 mga_vid_set_config(&mga_config); | |
546 return 0; | |
547 | |
548 } | |
549 case VIDIOCGWIN: | |
550 { | |
551 if(copy_to_user(arg, &mga_win, sizeof(mga_win))) | |
552 return -EFAULT; | |
553 return 0; | |
554 } | |
555 case VIDIOCCAPTURE: | |
556 { | |
557 int v; | |
558 if(copy_from_user(&v, arg, sizeof(v))) | |
559 return -EFAULT; | |
560 vid_overlay_on = v; | |
561 if(vid_overlay_on && vid_src_ready) | |
562 { | |
563 //regs.besctl |= 1; | |
564 mga_vid_write_regs(); | |
565 } | |
566 else | |
567 { | |
568 //regs.besctl &= ~1; | |
569 mga_vid_write_regs(); | |
570 } | |
571 return 0; | |
572 } | |
573 default: | |
574 return -ENOIOCTLCMD; | |
575 } | |
576 } | |
577 | |
578 static struct video_device mga_v4l_dev = | |
579 { | |
580 "Matrox G200/G400", | |
581 VID_TYPE_CAPTURE, | |
582 VID_HARDWARE_BT848, /* This is a lie for now */ | |
583 mga_v4l_open, | |
584 mga_v4l_close, | |
585 mga_v4l_read, | |
586 mga_v4l_write, | |
587 NULL, | |
588 mga_v4l_ioctl, | |
589 NULL, | |
590 mga_v4l_init_done, | |
591 NULL, | |
592 0, | |
593 0 | |
594 }; | |
595 | |
596 #endif | |
597 | |
598 /* | |
599 * Main Initialization Function | |
600 */ | |
601 | |
602 | |
603 static int mga_vid_initialize(void) | |
604 { | |
605 mga_vid_in_use = 0; | |
606 | |
62 | 607 printk(KERN_DEBUG "SiS 6326 YUV Video interface v0.01 (c) Aaron Holtzman \n"); |
1 | 608 if(register_chrdev(MGA_VID_MAJOR, "mga_vid", &mga_vid_fops)) |
609 { | |
62 | 610 printk(KERN_ERR "sis_vid: unable to get major: %d\n", MGA_VID_MAJOR); |
1 | 611 return -EIO; |
612 } | |
613 | |
614 if (!mga_vid_find_card()) | |
615 { | |
62 | 616 printk(KERN_ERR "sis_vid: no supported devices found\n"); |
1 | 617 unregister_chrdev(MGA_VID_MAJOR, "mga_vid"); |
618 return -EINVAL; | |
619 } | |
620 | |
621 #if 0 | |
622 if (video_register_device(&mga_v4l_dev, VFL_TYPE_GRABBER)<0) | |
623 { | |
624 printk("sis_vid: unable to register.\n"); | |
625 unregister_chrdev(MGA_VID_MAJOR, "mga_vid"); | |
626 if(mga_mmio_base) | |
627 iounmap(mga_mmio_base); | |
628 mga_mmio_base = 0; | |
629 return -EINVAL; | |
630 } | |
631 #endif | |
632 | |
633 return(0); | |
634 } | |
635 | |
636 int init_module(void) | |
637 { | |
638 return mga_vid_initialize(); | |
639 } | |
640 | |
641 void cleanup_module(void) | |
642 { | |
643 // video_unregister_device(&mga_v4l_dev); | |
644 if(mga_mmio_base) | |
645 iounmap(mga_mmio_base); | |
646 | |
647 //FIXME turn off BES | |
62 | 648 printk(KERN_DEBUG "mga_vid: Cleaning up module\n"); |
1 | 649 unregister_chrdev(MGA_VID_MAJOR, "mga_vid"); |
650 } | |
651 |