GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / media / video / pms.c
blob7129b50757dbd7605fa13449bd7793511019f52f
1 /*
2 * Media Vision Pro Movie Studio
3 * or
4 * "all you need is an I2C bus some RAM and a prayer"
6 * This draws heavily on code
8 * (c) Wolfgang Koehler, wolf@first.gmd.de, Dec. 1994
9 * Kiefernring 15
10 * 14478 Potsdam, Germany
12 * Most of this code is directly derived from his userspace driver.
13 * His driver works so send any reports to alan@lxorguk.ukuu.org.uk
14 * unless the userspace driver also doesn't work for you...
16 * Changes:
17 * 25-11-2009 Hans Verkuil <hverkuil@xs4all.nl>
18 * - converted to version 2 of the V4L API.
19 * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
20 * - pms_capture: report back -EFAULT
23 #include <linux/module.h>
24 #include <linux/delay.h>
25 #include <linux/errno.h>
26 #include <linux/fs.h>
27 #include <linux/kernel.h>
28 #include <linux/mm.h>
29 #include <linux/ioport.h>
30 #include <linux/init.h>
31 #include <linux/version.h>
32 #include <linux/mutex.h>
33 #include <linux/uaccess.h>
34 #include <asm/io.h>
36 #include <linux/videodev2.h>
37 #include <media/v4l2-common.h>
38 #include <media/v4l2-ioctl.h>
39 #include <media/v4l2-device.h>
41 MODULE_LICENSE("GPL");
44 #define MOTOROLA 1
45 #define PHILIPS2 2 /* SAA7191 */
46 #define PHILIPS1 3
47 #define MVVMEMORYWIDTH 0x40 /* 512 bytes */
49 struct i2c_info {
50 u8 slave;
51 u8 sub;
52 u8 data;
53 u8 hits;
56 struct pms {
57 struct v4l2_device v4l2_dev;
58 struct video_device vdev;
59 int height;
60 int width;
61 int depth;
62 int input;
63 s32 brightness, saturation, hue, contrast;
64 struct mutex lock;
65 int i2c_count;
66 struct i2c_info i2cinfo[64];
68 int decoder;
69 int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
70 v4l2_std_id std;
71 int io;
72 int data;
73 void __iomem *mem;
76 static struct pms pms_card;
79 * I/O ports and Shared Memory
82 static int io_port = 0x250;
83 module_param(io_port, int, 0);
85 static int mem_base = 0xc8000;
86 module_param(mem_base, int, 0);
88 static int video_nr = -1;
89 module_param(video_nr, int, 0);
92 static inline void mvv_write(struct pms *dev, u8 index, u8 value)
94 outw(index | (value << 8), dev->io);
97 static inline u8 mvv_read(struct pms *dev, u8 index)
99 outb(index, dev->io);
100 return inb(dev->data);
103 static int pms_i2c_stat(struct pms *dev, u8 slave)
105 int counter = 0;
106 int i;
108 outb(0x28, dev->io);
110 while ((inb(dev->data) & 0x01) == 0)
111 if (counter++ == 256)
112 break;
114 while ((inb(dev->data) & 0x01) != 0)
115 if (counter++ == 256)
116 break;
118 outb(slave, dev->io);
120 counter = 0;
121 while ((inb(dev->data) & 0x01) == 0)
122 if (counter++ == 256)
123 break;
125 while ((inb(dev->data) & 0x01) != 0)
126 if (counter++ == 256)
127 break;
129 for (i = 0; i < 12; i++) {
130 char st = inb(dev->data);
132 if ((st & 2) != 0)
133 return -1;
134 if ((st & 1) == 0)
135 break;
137 outb(0x29, dev->io);
138 return inb(dev->data);
141 static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data)
143 int skip = 0;
144 int count;
145 int i;
147 for (i = 0; i < dev->i2c_count; i++) {
148 if ((dev->i2cinfo[i].slave == slave) &&
149 (dev->i2cinfo[i].sub == sub)) {
150 if (dev->i2cinfo[i].data == data)
151 skip = 1;
152 dev->i2cinfo[i].data = data;
153 i = dev->i2c_count + 1;
157 if (i == dev->i2c_count && dev->i2c_count < 64) {
158 dev->i2cinfo[dev->i2c_count].slave = slave;
159 dev->i2cinfo[dev->i2c_count].sub = sub;
160 dev->i2cinfo[dev->i2c_count].data = data;
161 dev->i2c_count++;
164 if (skip)
165 return 0;
167 mvv_write(dev, 0x29, sub);
168 mvv_write(dev, 0x2A, data);
169 mvv_write(dev, 0x28, slave);
171 outb(0x28, dev->io);
173 count = 0;
174 while ((inb(dev->data) & 1) == 0)
175 if (count > 255)
176 break;
177 while ((inb(dev->data) & 1) != 0)
178 if (count > 255)
179 break;
181 count = inb(dev->data);
183 if (count & 2)
184 return -1;
185 return count;
188 static int pms_i2c_read(struct pms *dev, int slave, int sub)
190 int i;
192 for (i = 0; i < dev->i2c_count; i++) {
193 if (dev->i2cinfo[i].slave == slave && dev->i2cinfo[i].sub == sub)
194 return dev->i2cinfo[i].data;
196 return 0;
200 static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or)
202 u8 tmp;
204 tmp = pms_i2c_read(dev, slave, sub);
205 tmp = (tmp & and) | or;
206 pms_i2c_write(dev, slave, sub, tmp);
210 * Control functions
214 static void pms_videosource(struct pms *dev, short source)
216 switch (dev->decoder) {
217 case MOTOROLA:
218 break;
219 case PHILIPS2:
220 pms_i2c_andor(dev, 0x8a, 0x06, 0x7f, source ? 0x80 : 0);
221 break;
222 case PHILIPS1:
223 break;
225 mvv_write(dev, 0x2E, 0x31);
226 /* Was: mvv_write(dev, 0x2E, source ? 0x31 : 0x30);
227 But could not make this work correctly. Only Composite input
228 worked for me. */
231 static void pms_hue(struct pms *dev, short hue)
233 switch (dev->decoder) {
234 case MOTOROLA:
235 pms_i2c_write(dev, 0x8a, 0x00, hue);
236 break;
237 case PHILIPS2:
238 pms_i2c_write(dev, 0x8a, 0x07, hue);
239 break;
240 case PHILIPS1:
241 pms_i2c_write(dev, 0x42, 0x07, hue);
242 break;
246 static void pms_saturation(struct pms *dev, short sat)
248 switch (dev->decoder) {
249 case MOTOROLA:
250 pms_i2c_write(dev, 0x8a, 0x00, sat);
251 break;
252 case PHILIPS1:
253 pms_i2c_write(dev, 0x42, 0x12, sat);
254 break;
259 static void pms_contrast(struct pms *dev, short contrast)
261 switch (dev->decoder) {
262 case MOTOROLA:
263 pms_i2c_write(dev, 0x8a, 0x00, contrast);
264 break;
265 case PHILIPS1:
266 pms_i2c_write(dev, 0x42, 0x13, contrast);
267 break;
271 static void pms_brightness(struct pms *dev, short brightness)
273 switch (dev->decoder) {
274 case MOTOROLA:
275 pms_i2c_write(dev, 0x8a, 0x00, brightness);
276 pms_i2c_write(dev, 0x8a, 0x00, brightness);
277 pms_i2c_write(dev, 0x8a, 0x00, brightness);
278 break;
279 case PHILIPS1:
280 pms_i2c_write(dev, 0x42, 0x19, brightness);
281 break;
286 static void pms_format(struct pms *dev, short format)
288 int target;
290 dev->standard = format;
292 if (dev->decoder == PHILIPS1)
293 target = 0x42;
294 else if (dev->decoder == PHILIPS2)
295 target = 0x8a;
296 else
297 return;
299 switch (format) {
300 case 0: /* Auto */
301 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
302 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x80);
303 break;
304 case 1: /* NTSC */
305 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
306 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x40);
307 break;
308 case 2: /* PAL */
309 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
310 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
311 break;
312 case 3: /* SECAM */
313 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x01);
314 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
315 break;
319 #ifdef FOR_FUTURE_EXPANSION
322 * These features of the PMS card are not currently exposes. They
323 * could become a private v4l ioctl for PMSCONFIG or somesuch if
324 * people need it. We also don't yet use the PMS interrupt.
327 static void pms_hstart(struct pms *dev, short start)
329 switch (dev->decoder) {
330 case PHILIPS1:
331 pms_i2c_write(dev, 0x8a, 0x05, start);
332 pms_i2c_write(dev, 0x8a, 0x18, start);
333 break;
334 case PHILIPS2:
335 pms_i2c_write(dev, 0x42, 0x05, start);
336 pms_i2c_write(dev, 0x42, 0x18, start);
337 break;
342 * Bandpass filters
345 static void pms_bandpass(struct pms *dev, short pass)
347 if (dev->decoder == PHILIPS2)
348 pms_i2c_andor(dev, 0x8a, 0x06, 0xcf, (pass & 0x03) << 4);
349 else if (dev->decoder == PHILIPS1)
350 pms_i2c_andor(dev, 0x42, 0x06, 0xcf, (pass & 0x03) << 4);
353 static void pms_antisnow(struct pms *dev, short snow)
355 if (dev->decoder == PHILIPS2)
356 pms_i2c_andor(dev, 0x8a, 0x06, 0xf3, (snow & 0x03) << 2);
357 else if (dev->decoder == PHILIPS1)
358 pms_i2c_andor(dev, 0x42, 0x06, 0xf3, (snow & 0x03) << 2);
361 static void pms_sharpness(struct pms *dev, short sharp)
363 if (dev->decoder == PHILIPS2)
364 pms_i2c_andor(dev, 0x8a, 0x06, 0xfc, sharp & 0x03);
365 else if (dev->decoder == PHILIPS1)
366 pms_i2c_andor(dev, 0x42, 0x06, 0xfc, sharp & 0x03);
369 static void pms_chromaagc(struct pms *dev, short agc)
371 if (dev->decoder == PHILIPS2)
372 pms_i2c_andor(dev, 0x8a, 0x0c, 0x9f, (agc & 0x03) << 5);
373 else if (dev->decoder == PHILIPS1)
374 pms_i2c_andor(dev, 0x42, 0x0c, 0x9f, (agc & 0x03) << 5);
377 static void pms_vertnoise(struct pms *dev, short noise)
379 if (dev->decoder == PHILIPS2)
380 pms_i2c_andor(dev, 0x8a, 0x10, 0xfc, noise & 3);
381 else if (dev->decoder == PHILIPS1)
382 pms_i2c_andor(dev, 0x42, 0x10, 0xfc, noise & 3);
385 static void pms_forcecolour(struct pms *dev, short colour)
387 if (dev->decoder == PHILIPS2)
388 pms_i2c_andor(dev, 0x8a, 0x0c, 0x7f, (colour & 1) << 7);
389 else if (dev->decoder == PHILIPS1)
390 pms_i2c_andor(dev, 0x42, 0x0c, 0x7, (colour & 1) << 7);
393 static void pms_antigamma(struct pms *dev, short gamma)
395 if (dev->decoder == PHILIPS2)
396 pms_i2c_andor(dev, 0xb8, 0x00, 0x7f, (gamma & 1) << 7);
397 else if (dev->decoder == PHILIPS1)
398 pms_i2c_andor(dev, 0x42, 0x20, 0x7, (gamma & 1) << 7);
401 static void pms_prefilter(struct pms *dev, short filter)
403 if (dev->decoder == PHILIPS2)
404 pms_i2c_andor(dev, 0x8a, 0x06, 0xbf, (filter & 1) << 6);
405 else if (dev->decoder == PHILIPS1)
406 pms_i2c_andor(dev, 0x42, 0x06, 0xbf, (filter & 1) << 6);
409 static void pms_hfilter(struct pms *dev, short filter)
411 if (dev->decoder == PHILIPS2)
412 pms_i2c_andor(dev, 0xb8, 0x04, 0x1f, (filter & 7) << 5);
413 else if (dev->decoder == PHILIPS1)
414 pms_i2c_andor(dev, 0x42, 0x24, 0x1f, (filter & 7) << 5);
417 static void pms_vfilter(struct pms *dev, short filter)
419 if (dev->decoder == PHILIPS2)
420 pms_i2c_andor(dev, 0xb8, 0x08, 0x9f, (filter & 3) << 5);
421 else if (dev->decoder == PHILIPS1)
422 pms_i2c_andor(dev, 0x42, 0x28, 0x9f, (filter & 3) << 5);
425 static void pms_killcolour(struct pms *dev, short colour)
427 if (dev->decoder == PHILIPS2) {
428 pms_i2c_andor(dev, 0x8a, 0x08, 0x07, (colour & 0x1f) << 3);
429 pms_i2c_andor(dev, 0x8a, 0x09, 0x07, (colour & 0x1f) << 3);
430 } else if (dev->decoder == PHILIPS1) {
431 pms_i2c_andor(dev, 0x42, 0x08, 0x07, (colour & 0x1f) << 3);
432 pms_i2c_andor(dev, 0x42, 0x09, 0x07, (colour & 0x1f) << 3);
436 static void pms_chromagain(struct pms *dev, short chroma)
438 if (dev->decoder == PHILIPS2)
439 pms_i2c_write(dev, 0x8a, 0x11, chroma);
440 else if (dev->decoder == PHILIPS1)
441 pms_i2c_write(dev, 0x42, 0x11, chroma);
445 static void pms_spacialcompl(struct pms *dev, short data)
447 mvv_write(dev, 0x3b, data);
450 static void pms_spacialcomph(struct pms *dev, short data)
452 mvv_write(dev, 0x3a, data);
455 static void pms_vstart(struct pms *dev, short start)
457 mvv_write(dev, 0x16, start);
458 mvv_write(dev, 0x17, (start >> 8) & 0x01);
461 #endif
463 static void pms_secamcross(struct pms *dev, short cross)
465 if (dev->decoder == PHILIPS2)
466 pms_i2c_andor(dev, 0x8a, 0x0f, 0xdf, (cross & 1) << 5);
467 else if (dev->decoder == PHILIPS1)
468 pms_i2c_andor(dev, 0x42, 0x0f, 0xdf, (cross & 1) << 5);
472 static void pms_swsense(struct pms *dev, short sense)
474 if (dev->decoder == PHILIPS2) {
475 pms_i2c_write(dev, 0x8a, 0x0a, sense);
476 pms_i2c_write(dev, 0x8a, 0x0b, sense);
477 } else if (dev->decoder == PHILIPS1) {
478 pms_i2c_write(dev, 0x42, 0x0a, sense);
479 pms_i2c_write(dev, 0x42, 0x0b, sense);
484 static void pms_framerate(struct pms *dev, short frr)
486 int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25;
488 if (frr == 0)
489 return;
490 fps = fps/frr;
491 mvv_write(dev, 0x14, 0x80 | fps);
492 mvv_write(dev, 0x15, 1);
495 static void pms_vert(struct pms *dev, u8 deciden, u8 decinum)
497 mvv_write(dev, 0x1c, deciden); /* Denominator */
498 mvv_write(dev, 0x1d, decinum); /* Numerator */
502 * Turn 16bit ratios into best small ratio the chipset can grok
505 static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden)
507 /* Knock it down by / 5 once */
508 if (decinum % 5 == 0) {
509 deciden /= 5;
510 decinum /= 5;
513 * 3's
515 while (decinum % 3 == 0 && deciden % 3 == 0) {
516 deciden /= 3;
517 decinum /= 3;
520 * 2's
522 while (decinum % 2 == 0 && deciden % 2 == 0) {
523 decinum /= 2;
524 deciden /= 2;
527 * Fudgyify
529 while (deciden > 32) {
530 deciden /= 2;
531 decinum = (decinum + 1) / 2;
533 if (deciden == 32)
534 deciden--;
535 pms_vert(dev, deciden, decinum);
538 static void pms_horzdeci(struct pms *dev, short decinum, short deciden)
540 if (decinum <= 512) {
541 if (decinum % 5 == 0) {
542 decinum /= 5;
543 deciden /= 5;
545 } else {
546 decinum = 512;
547 deciden = 640; /* 768 would be ideal */
550 while (((decinum | deciden) & 1) == 0) {
551 decinum >>= 1;
552 deciden >>= 1;
554 while (deciden > 32) {
555 deciden >>= 1;
556 decinum = (decinum + 1) >> 1;
558 if (deciden == 32)
559 deciden--;
561 mvv_write(dev, 0x24, 0x80 | deciden);
562 mvv_write(dev, 0x25, decinum);
565 static void pms_resolution(struct pms *dev, short width, short height)
567 int fg_height;
569 fg_height = height;
570 if (fg_height > 280)
571 fg_height = 280;
573 mvv_write(dev, 0x18, fg_height);
574 mvv_write(dev, 0x19, fg_height >> 8);
576 if (dev->std & V4L2_STD_525_60) {
577 mvv_write(dev, 0x1a, 0xfc);
578 mvv_write(dev, 0x1b, 0x00);
579 if (height > fg_height)
580 pms_vertdeci(dev, 240, 240);
581 else
582 pms_vertdeci(dev, fg_height, 240);
583 } else {
584 mvv_write(dev, 0x1a, 0x1a);
585 mvv_write(dev, 0x1b, 0x01);
586 if (fg_height > 256)
587 pms_vertdeci(dev, 270, 270);
588 else
589 pms_vertdeci(dev, fg_height, 270);
591 mvv_write(dev, 0x12, 0);
592 mvv_write(dev, 0x13, MVVMEMORYWIDTH);
593 mvv_write(dev, 0x42, 0x00);
594 mvv_write(dev, 0x43, 0x00);
595 mvv_write(dev, 0x44, MVVMEMORYWIDTH);
597 mvv_write(dev, 0x22, width + 8);
598 mvv_write(dev, 0x23, (width + 8) >> 8);
600 if (dev->std & V4L2_STD_525_60)
601 pms_horzdeci(dev, width, 640);
602 else
603 pms_horzdeci(dev, width + 8, 768);
605 mvv_write(dev, 0x30, mvv_read(dev, 0x30) & 0xfe);
606 mvv_write(dev, 0x08, mvv_read(dev, 0x08) | 0x01);
607 mvv_write(dev, 0x01, mvv_read(dev, 0x01) & 0xfd);
608 mvv_write(dev, 0x32, 0x00);
609 mvv_write(dev, 0x33, MVVMEMORYWIDTH);
614 * Set Input
617 static void pms_vcrinput(struct pms *dev, short input)
619 if (dev->decoder == PHILIPS2)
620 pms_i2c_andor(dev, 0x8a, 0x0d, 0x7f, (input & 1) << 7);
621 else if (dev->decoder == PHILIPS1)
622 pms_i2c_andor(dev, 0x42, 0x0d, 0x7f, (input & 1) << 7);
626 static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
628 int y;
629 int dw = 2 * dev->width;
630 char tmp[dw + 32]; /* using a temp buffer is faster than direct */
631 int cnt = 0;
632 int len = 0;
633 unsigned char r8 = 0x5; /* value for reg8 */
635 if (rgb555)
636 r8 |= 0x20; /* else use untranslated rgb = 565 */
637 mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
639 /* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
641 for (y = 0; y < dev->height; y++) {
642 writeb(0, dev->mem); /* synchronisiert neue Zeile */
645 * This is in truth a fifo, be very careful as if you
646 * forgot this odd things will occur 8)
649 memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word */
650 cnt -= dev->height;
651 while (cnt <= 0) {
653 * Don't copy too far
655 int dt = dw;
656 if (dt + len > count)
657 dt = count - len;
658 cnt += dev->height;
659 if (copy_to_user(buf, tmp + 32, dt))
660 return len ? len : -EFAULT;
661 buf += dt;
662 len += dt;
665 return len;
670 * Video4linux interfacing
673 static int pms_querycap(struct file *file, void *priv,
674 struct v4l2_capability *vcap)
676 struct pms *dev = video_drvdata(file);
678 strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver));
679 strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card));
680 strlcpy(vcap->bus_info, "ISA", sizeof(vcap->bus_info));
681 vcap->version = KERNEL_VERSION(0, 0, 3);
682 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
683 return 0;
686 static int pms_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
688 static const char *inputs[4] = {
689 "Composite",
690 "S-Video",
691 "Composite (VCR)",
692 "S-Video (VCR)"
695 if (vin->index > 3)
696 return -EINVAL;
697 strlcpy(vin->name, inputs[vin->index], sizeof(vin->name));
698 vin->type = V4L2_INPUT_TYPE_CAMERA;
699 vin->audioset = 0;
700 vin->tuner = 0;
701 vin->std = V4L2_STD_ALL;
702 vin->status = 0;
703 return 0;
706 static int pms_g_input(struct file *file, void *fh, unsigned int *inp)
708 struct pms *dev = video_drvdata(file);
710 *inp = dev->input;
711 return 0;
714 static int pms_s_input(struct file *file, void *fh, unsigned int inp)
716 struct pms *dev = video_drvdata(file);
718 if (inp > 3)
719 return -EINVAL;
721 mutex_lock(&dev->lock);
722 dev->input = inp;
723 pms_videosource(dev, inp & 1);
724 pms_vcrinput(dev, inp >> 1);
725 mutex_unlock(&dev->lock);
726 return 0;
729 static int pms_g_std(struct file *file, void *fh, v4l2_std_id *std)
731 struct pms *dev = video_drvdata(file);
733 *std = dev->std;
734 return 0;
737 static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std)
739 struct pms *dev = video_drvdata(file);
740 int ret = 0;
742 dev->std = *std;
743 mutex_lock(&dev->lock);
744 if (dev->std & V4L2_STD_NTSC) {
745 pms_framerate(dev, 30);
746 pms_secamcross(dev, 0);
747 pms_format(dev, 1);
748 } else if (dev->std & V4L2_STD_PAL) {
749 pms_framerate(dev, 25);
750 pms_secamcross(dev, 0);
751 pms_format(dev, 2);
752 } else if (dev->std & V4L2_STD_SECAM) {
753 pms_framerate(dev, 25);
754 pms_secamcross(dev, 1);
755 pms_format(dev, 2);
756 } else {
757 ret = -EINVAL;
760 switch (v->mode) {
761 case VIDEO_MODE_AUTO:
762 pms_framerate(dev, 25);
763 pms_secamcross(dev, 0);
764 pms_format(dev, 0);
765 break;
767 mutex_unlock(&dev->lock);
768 return 0;
771 static int pms_queryctrl(struct file *file, void *priv,
772 struct v4l2_queryctrl *qc)
774 switch (qc->id) {
775 case V4L2_CID_BRIGHTNESS:
776 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 139);
777 case V4L2_CID_CONTRAST:
778 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 70);
779 case V4L2_CID_SATURATION:
780 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 64);
781 case V4L2_CID_HUE:
782 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
784 return -EINVAL;
787 static int pms_g_ctrl(struct file *file, void *priv,
788 struct v4l2_control *ctrl)
790 struct pms *dev = video_drvdata(file);
791 int ret = 0;
793 switch (ctrl->id) {
794 case V4L2_CID_BRIGHTNESS:
795 ctrl->value = dev->brightness;
796 break;
797 case V4L2_CID_CONTRAST:
798 ctrl->value = dev->contrast;
799 break;
800 case V4L2_CID_SATURATION:
801 ctrl->value = dev->saturation;
802 break;
803 case V4L2_CID_HUE:
804 ctrl->value = dev->hue;
805 break;
806 default:
807 ret = -EINVAL;
808 break;
810 return ret;
813 static int pms_s_ctrl(struct file *file, void *priv,
814 struct v4l2_control *ctrl)
816 struct pms *dev = video_drvdata(file);
817 int ret = 0;
819 mutex_lock(&dev->lock);
820 switch (ctrl->id) {
821 case V4L2_CID_BRIGHTNESS:
822 dev->brightness = ctrl->value;
823 pms_brightness(dev, dev->brightness);
824 break;
825 case V4L2_CID_CONTRAST:
826 dev->contrast = ctrl->value;
827 pms_contrast(dev, dev->contrast);
828 break;
829 case V4L2_CID_SATURATION:
830 dev->saturation = ctrl->value;
831 pms_saturation(dev, dev->saturation);
832 break;
833 case V4L2_CID_HUE:
834 dev->hue = ctrl->value;
835 pms_hue(dev, dev->hue);
836 break;
837 default:
838 ret = -EINVAL;
839 break;
841 mutex_unlock(&dev->lock);
842 return ret;
845 static int pms_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
847 struct pms *dev = video_drvdata(file);
848 struct v4l2_pix_format *pix = &fmt->fmt.pix;
850 pix->width = dev->width;
851 pix->height = dev->height;
852 pix->pixelformat = dev->width == 15 ?
853 V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB565;
854 pix->field = V4L2_FIELD_NONE;
855 pix->bytesperline = 2 * dev->width;
856 pix->sizeimage = 2 * dev->width * dev->height;
857 /* Just a guess */
858 pix->colorspace = V4L2_COLORSPACE_SRGB;
859 return 0;
862 static int pms_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
864 struct v4l2_pix_format *pix = &fmt->fmt.pix;
866 if (pix->height < 16 || pix->height > 480)
867 return -EINVAL;
868 if (pix->width < 16 || pix->width > 640)
869 return -EINVAL;
870 if (pix->pixelformat != V4L2_PIX_FMT_RGB555 &&
871 pix->pixelformat != V4L2_PIX_FMT_RGB565)
872 return -EINVAL;
873 pix->field = V4L2_FIELD_NONE;
874 pix->bytesperline = 2 * pix->width;
875 pix->sizeimage = 2 * pix->width * pix->height;
876 /* Just a guess */
877 pix->colorspace = V4L2_COLORSPACE_SRGB;
878 return 0;
881 static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
883 struct pms *dev = video_drvdata(file);
884 struct v4l2_pix_format *pix = &fmt->fmt.pix;
885 int ret = pms_try_fmt_vid_cap(file, fh, fmt);
887 if (ret)
888 return ret;
889 mutex_lock(&dev->lock);
890 dev->width = pix->width;
891 dev->height = pix->height;
892 dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16;
893 pms_resolution(dev, dev->width, dev->height);
894 /* Ok we figured out what to use from our wide choice */
895 mutex_unlock(&dev->lock);
896 return 0;
899 static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
901 static struct v4l2_fmtdesc formats[] = {
902 { 0, 0, 0,
903 "RGB 5:5:5", V4L2_PIX_FMT_RGB555,
904 { 0, 0, 0, 0 }
906 { 0, 0, 0,
907 "RGB 5:6:5", V4L2_PIX_FMT_RGB565,
908 { 0, 0, 0, 0 }
911 enum v4l2_buf_type type = fmt->type;
913 if (fmt->index > 1)
914 return -EINVAL;
916 *fmt = formats[fmt->index];
917 fmt->type = type;
918 return 0;
921 static ssize_t pms_read(struct file *file, char __user *buf,
922 size_t count, loff_t *ppos)
924 struct pms *dev = video_drvdata(file);
925 int len;
927 mutex_lock(&dev->lock);
928 len = pms_capture(dev, buf, (dev->depth == 15), count);
929 mutex_unlock(&dev->lock);
930 return len;
933 static const struct v4l2_file_operations pms_fops = {
934 .owner = THIS_MODULE,
935 .ioctl = video_ioctl2,
936 .read = pms_read,
939 static const struct v4l2_ioctl_ops pms_ioctl_ops = {
940 .vidioc_querycap = pms_querycap,
941 .vidioc_g_input = pms_g_input,
942 .vidioc_s_input = pms_s_input,
943 .vidioc_enum_input = pms_enum_input,
944 .vidioc_g_std = pms_g_std,
945 .vidioc_s_std = pms_s_std,
946 .vidioc_queryctrl = pms_queryctrl,
947 .vidioc_g_ctrl = pms_g_ctrl,
948 .vidioc_s_ctrl = pms_s_ctrl,
949 .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap,
950 .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap,
951 .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap,
952 .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap,
956 * Probe for and initialise the Mediavision PMS
959 static int init_mediavision(struct pms *dev)
961 int id;
962 int idec, decst;
963 int i;
964 static const unsigned char i2c_defs[] = {
965 0x4c, 0x30, 0x00, 0xe8,
966 0xb6, 0xe2, 0x00, 0x00,
967 0xff, 0xff, 0x00, 0x00,
968 0x00, 0x00, 0x78, 0x98,
969 0x00, 0x00, 0x00, 0x00,
970 0x34, 0x0a, 0xf4, 0xce,
971 0xe4
974 dev->mem = ioremap(mem_base, 0x800);
975 if (!dev->mem)
976 return -ENOMEM;
978 if (!request_region(0x9a01, 1, "Mediavision PMS config")) {
979 printk(KERN_WARNING "mediavision: unable to detect: 0x9a01 in use.\n");
980 iounmap(dev->mem);
981 return -EBUSY;
983 if (!request_region(dev->io, 3, "Mediavision PMS")) {
984 printk(KERN_WARNING "mediavision: I/O port %d in use.\n", dev->io);
985 release_region(0x9a01, 1);
986 iounmap(dev->mem);
987 return -EBUSY;
989 outb(0xb8, 0x9a01); /* Unlock */
990 outb(dev->io >> 4, 0x9a01); /* Set IO port */
993 id = mvv_read(dev, 3);
994 decst = pms_i2c_stat(dev, 0x43);
996 if (decst != -1)
997 idec = 2;
998 else if (pms_i2c_stat(dev, 0xb9) != -1)
999 idec = 3;
1000 else if (pms_i2c_stat(dev, 0x8b) != -1)
1001 idec = 1;
1002 else
1003 idec = 0;
1005 printk(KERN_INFO "PMS type is %d\n", idec);
1006 if (idec == 0) {
1007 release_region(dev->io, 3);
1008 release_region(0x9a01, 1);
1009 iounmap(dev->mem);
1010 return -ENODEV;
1014 * Ok we have a PMS of some sort
1017 mvv_write(dev, 0x04, mem_base >> 12); /* Set the memory area */
1019 /* Ok now load the defaults */
1021 for (i = 0; i < 0x19; i++) {
1022 if (i2c_defs[i] == 0xff)
1023 pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00);
1024 else
1025 pms_i2c_write(dev, 0x8a, i, i2c_defs[i]);
1028 pms_i2c_write(dev, 0xb8, 0x00, 0x12);
1029 pms_i2c_write(dev, 0xb8, 0x04, 0x00);
1030 pms_i2c_write(dev, 0xb8, 0x07, 0x00);
1031 pms_i2c_write(dev, 0xb8, 0x08, 0x00);
1032 pms_i2c_write(dev, 0xb8, 0x09, 0xff);
1033 pms_i2c_write(dev, 0xb8, 0x0a, 0x00);
1034 pms_i2c_write(dev, 0xb8, 0x0b, 0x10);
1035 pms_i2c_write(dev, 0xb8, 0x10, 0x03);
1037 mvv_write(dev, 0x01, 0x00);
1038 mvv_write(dev, 0x05, 0xa0);
1039 mvv_write(dev, 0x08, 0x25);
1040 mvv_write(dev, 0x09, 0x00);
1041 mvv_write(dev, 0x0a, 0x20 | MVVMEMORYWIDTH);
1043 mvv_write(dev, 0x10, 0x02);
1044 mvv_write(dev, 0x1e, 0x0c);
1045 mvv_write(dev, 0x1f, 0x03);
1046 mvv_write(dev, 0x26, 0x06);
1048 mvv_write(dev, 0x2b, 0x00);
1049 mvv_write(dev, 0x2c, 0x20);
1050 mvv_write(dev, 0x2d, 0x00);
1051 mvv_write(dev, 0x2f, 0x70);
1052 mvv_write(dev, 0x32, 0x00);
1053 mvv_write(dev, 0x33, MVVMEMORYWIDTH);
1054 mvv_write(dev, 0x34, 0x00);
1055 mvv_write(dev, 0x35, 0x00);
1056 mvv_write(dev, 0x3a, 0x80);
1057 mvv_write(dev, 0x3b, 0x10);
1058 mvv_write(dev, 0x20, 0x00);
1059 mvv_write(dev, 0x21, 0x00);
1060 mvv_write(dev, 0x30, 0x22);
1061 return 0;
1065 * Initialization and module stuff
1068 #ifndef MODULE
1069 static int enable;
1070 module_param(enable, int, 0);
1071 #endif
1073 static int __init pms_init(void)
1075 struct pms *dev = &pms_card;
1076 struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
1077 int res;
1079 strlcpy(v4l2_dev->name, "pms", sizeof(v4l2_dev->name));
1081 v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.03\n");
1083 #ifndef MODULE
1084 if (!enable) {
1085 v4l2_err(v4l2_dev,
1086 "PMS: not enabled, use pms.enable=1 to probe\n");
1087 return -ENODEV;
1089 #endif
1091 dev->decoder = PHILIPS2;
1092 dev->io = io_port;
1093 dev->data = io_port + 1;
1095 if (init_mediavision(dev)) {
1096 v4l2_err(v4l2_dev, "Board not found.\n");
1097 return -ENODEV;
1100 res = v4l2_device_register(NULL, v4l2_dev);
1101 if (res < 0) {
1102 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
1103 return res;
1106 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
1107 dev->vdev.v4l2_dev = v4l2_dev;
1108 dev->vdev.fops = &pms_fops;
1109 dev->vdev.ioctl_ops = &pms_ioctl_ops;
1110 dev->vdev.release = video_device_release_empty;
1111 video_set_drvdata(&dev->vdev, dev);
1112 mutex_init(&dev->lock);
1113 dev->std = V4L2_STD_NTSC_M;
1114 dev->height = 240;
1115 dev->width = 320;
1116 dev->depth = 15;
1117 dev->brightness = 139;
1118 dev->contrast = 70;
1119 dev->hue = 0;
1120 dev->saturation = 64;
1121 pms_swsense(dev, 75);
1122 pms_resolution(dev, 320, 240);
1123 pms_videosource(dev, 0);
1124 pms_vcrinput(dev, 0);
1125 if (video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1126 v4l2_device_unregister(&dev->v4l2_dev);
1127 release_region(dev->io, 3);
1128 release_region(0x9a01, 1);
1129 iounmap(dev->mem);
1130 return -EINVAL;
1132 return 0;
1135 static void __exit pms_exit(void)
1137 struct pms *dev = &pms_card;
1139 video_unregister_device(&dev->vdev);
1140 release_region(dev->io, 3);
1141 release_region(0x9a01, 1);
1142 iounmap(dev->mem);
1145 module_init(pms_init);
1146 module_exit(pms_exit);