1 /*
2 * Media Vision Pro Movie Studio
3 * or
4 * "all you need is an I2C bus some RAM and a prayer"
5 *
6 * This draws heavily on code
7 *
8 * (c) Wolfgang Koehler, wolf@first.gmd.de, Dec. 1994
9 * Kiefernring 15
10 * 14478 Potsdam, Germany
11 *
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...
15 *
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
21 */
22
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/slab.h>
30 #include <linux/ioport.h>
31 #include <linux/init.h>
32 #include <linux/mutex.h>
33 #include <linux/uaccess.h>
34 #include <linux/isa.h>
35 #include <asm/io.h>
36
37 #include <linux/videodev2.h>
38 #include <media/v4l2-common.h>
39 #include <media/v4l2-ioctl.h>
40 #include <media/v4l2-ctrls.h>
41 #include <media/v4l2-fh.h>
42 #include <media/v4l2-event.h>
43 #include <media/v4l2-device.h>
44
45 MODULE_LICENSE("GPL");
46 MODULE_VERSION("0.0.5");
47
48 #define MOTOROLA 1
49 #define PHILIPS2 2 /* SAA7191 */
50 #define PHILIPS1 3
51 #define MVVMEMORYWIDTH 0x40 /* 512 bytes */
52
53 struct i2c_info {
54 u8 slave;
55 u8 sub;
56 u8 data;
57 u8 hits;
58 };
59
60 struct pms {
61 struct v4l2_device v4l2_dev;
62 struct video_device vdev;
63 struct v4l2_ctrl_handler hdl;
64 int height;
65 int width;
66 int depth;
67 int input;
68 struct mutex lock;
69 int i2c_count;
70 struct i2c_info i2cinfo[64];
71
72 int decoder;
73 int standard; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
74 v4l2_std_id std;
75 int io;
76 int data;
77 void __iomem *mem;
78 };
79
80 /*
81 * I/O ports and Shared Memory
82 */
83
84 static int io_port = 0x250;
85 module_param(io_port, int, 0);
86
87 static int mem_base = 0xc8000;
88 module_param(mem_base, int, 0);
89
90 static int video_nr = -1;
91 module_param(video_nr, int, 0);
92
93
mvv_write(struct pms * dev,u8 index,u8 value)94 static inline void mvv_write(struct pms *dev, u8 index, u8 value)
95 {
96 outw(index | (value << 8), dev->io);
97 }
98
mvv_read(struct pms * dev,u8 index)99 static inline u8 mvv_read(struct pms *dev, u8 index)
100 {
101 outb(index, dev->io);
102 return inb(dev->data);
103 }
104
pms_i2c_stat(struct pms * dev,u8 slave)105 static int pms_i2c_stat(struct pms *dev, u8 slave)
106 {
107 int counter = 0;
108 int i;
109
110 outb(0x28, dev->io);
111
112 while ((inb(dev->data) & 0x01) == 0)
113 if (counter++ == 256)
114 break;
115
116 while ((inb(dev->data) & 0x01) != 0)
117 if (counter++ == 256)
118 break;
119
120 outb(slave, dev->io);
121
122 counter = 0;
123 while ((inb(dev->data) & 0x01) == 0)
124 if (counter++ == 256)
125 break;
126
127 while ((inb(dev->data) & 0x01) != 0)
128 if (counter++ == 256)
129 break;
130
131 for (i = 0; i < 12; i++) {
132 char st = inb(dev->data);
133
134 if ((st & 2) != 0)
135 return -1;
136 if ((st & 1) == 0)
137 break;
138 }
139 outb(0x29, dev->io);
140 return inb(dev->data);
141 }
142
pms_i2c_write(struct pms * dev,u16 slave,u16 sub,u16 data)143 static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data)
144 {
145 int skip = 0;
146 int count;
147 int i;
148
149 for (i = 0; i < dev->i2c_count; i++) {
150 if ((dev->i2cinfo[i].slave == slave) &&
151 (dev->i2cinfo[i].sub == sub)) {
152 if (dev->i2cinfo[i].data == data)
153 skip = 1;
154 dev->i2cinfo[i].data = data;
155 i = dev->i2c_count + 1;
156 }
157 }
158
159 if (i == dev->i2c_count && dev->i2c_count < 64) {
160 dev->i2cinfo[dev->i2c_count].slave = slave;
161 dev->i2cinfo[dev->i2c_count].sub = sub;
162 dev->i2cinfo[dev->i2c_count].data = data;
163 dev->i2c_count++;
164 }
165
166 if (skip)
167 return 0;
168
169 mvv_write(dev, 0x29, sub);
170 mvv_write(dev, 0x2A, data);
171 mvv_write(dev, 0x28, slave);
172
173 outb(0x28, dev->io);
174
175 count = 0;
176 while ((inb(dev->data) & 1) == 0)
177 if (count > 255)
178 break;
179 while ((inb(dev->data) & 1) != 0)
180 if (count > 255)
181 break;
182
183 count = inb(dev->data);
184
185 if (count & 2)
186 return -1;
187 return count;
188 }
189
pms_i2c_read(struct pms * dev,int slave,int sub)190 static int pms_i2c_read(struct pms *dev, int slave, int sub)
191 {
192 int i;
193
194 for (i = 0; i < dev->i2c_count; i++) {
195 if (dev->i2cinfo[i].slave == slave && dev->i2cinfo[i].sub == sub)
196 return dev->i2cinfo[i].data;
197 }
198 return 0;
199 }
200
201
pms_i2c_andor(struct pms * dev,int slave,int sub,int and,int or)202 static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or)
203 {
204 u8 tmp;
205
206 tmp = pms_i2c_read(dev, slave, sub);
207 tmp = (tmp & and) | or;
208 pms_i2c_write(dev, slave, sub, tmp);
209 }
210
211 /*
212 * Control functions
213 */
214
215
pms_videosource(struct pms * dev,short source)216 static void pms_videosource(struct pms *dev, short source)
217 {
218 switch (dev->decoder) {
219 case MOTOROLA:
220 break;
221 case PHILIPS2:
222 pms_i2c_andor(dev, 0x8a, 0x06, 0x7f, source ? 0x80 : 0);
223 break;
224 case PHILIPS1:
225 break;
226 }
227 mvv_write(dev, 0x2E, 0x31);
228 /* Was: mvv_write(dev, 0x2E, source ? 0x31 : 0x30);
229 But could not make this work correctly. Only Composite input
230 worked for me. */
231 }
232
pms_hue(struct pms * dev,short hue)233 static void pms_hue(struct pms *dev, short hue)
234 {
235 switch (dev->decoder) {
236 case MOTOROLA:
237 pms_i2c_write(dev, 0x8a, 0x00, hue);
238 break;
239 case PHILIPS2:
240 pms_i2c_write(dev, 0x8a, 0x07, hue);
241 break;
242 case PHILIPS1:
243 pms_i2c_write(dev, 0x42, 0x07, hue);
244 break;
245 }
246 }
247
pms_saturation(struct pms * dev,short sat)248 static void pms_saturation(struct pms *dev, short sat)
249 {
250 switch (dev->decoder) {
251 case MOTOROLA:
252 pms_i2c_write(dev, 0x8a, 0x00, sat);
253 break;
254 case PHILIPS1:
255 pms_i2c_write(dev, 0x42, 0x12, sat);
256 break;
257 }
258 }
259
260
pms_contrast(struct pms * dev,short contrast)261 static void pms_contrast(struct pms *dev, short contrast)
262 {
263 switch (dev->decoder) {
264 case MOTOROLA:
265 pms_i2c_write(dev, 0x8a, 0x00, contrast);
266 break;
267 case PHILIPS1:
268 pms_i2c_write(dev, 0x42, 0x13, contrast);
269 break;
270 }
271 }
272
pms_brightness(struct pms * dev,short brightness)273 static void pms_brightness(struct pms *dev, short brightness)
274 {
275 switch (dev->decoder) {
276 case MOTOROLA:
277 pms_i2c_write(dev, 0x8a, 0x00, brightness);
278 pms_i2c_write(dev, 0x8a, 0x00, brightness);
279 pms_i2c_write(dev, 0x8a, 0x00, brightness);
280 break;
281 case PHILIPS1:
282 pms_i2c_write(dev, 0x42, 0x19, brightness);
283 break;
284 }
285 }
286
287
pms_format(struct pms * dev,short format)288 static void pms_format(struct pms *dev, short format)
289 {
290 int target;
291
292 dev->standard = format;
293
294 if (dev->decoder == PHILIPS1)
295 target = 0x42;
296 else if (dev->decoder == PHILIPS2)
297 target = 0x8a;
298 else
299 return;
300
301 switch (format) {
302 case 0: /* Auto */
303 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
304 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x80);
305 break;
306 case 1: /* NTSC */
307 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
308 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x40);
309 break;
310 case 2: /* PAL */
311 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x00);
312 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
313 break;
314 case 3: /* SECAM */
315 pms_i2c_andor(dev, target, 0x0d, 0xfe, 0x01);
316 pms_i2c_andor(dev, target, 0x0f, 0x3f, 0x00);
317 break;
318 }
319 }
320
321 #ifdef FOR_FUTURE_EXPANSION
322
323 /*
324 * These features of the PMS card are not currently exposes. They
325 * could become a private v4l ioctl for PMSCONFIG or somesuch if
326 * people need it. We also don't yet use the PMS interrupt.
327 */
328
pms_hstart(struct pms * dev,short start)329 static void pms_hstart(struct pms *dev, short start)
330 {
331 switch (dev->decoder) {
332 case PHILIPS1:
333 pms_i2c_write(dev, 0x8a, 0x05, start);
334 pms_i2c_write(dev, 0x8a, 0x18, start);
335 break;
336 case PHILIPS2:
337 pms_i2c_write(dev, 0x42, 0x05, start);
338 pms_i2c_write(dev, 0x42, 0x18, start);
339 break;
340 }
341 }
342
343 /*
344 * Bandpass filters
345 */
346
pms_bandpass(struct pms * dev,short pass)347 static void pms_bandpass(struct pms *dev, short pass)
348 {
349 if (dev->decoder == PHILIPS2)
350 pms_i2c_andor(dev, 0x8a, 0x06, 0xcf, (pass & 0x03) << 4);
351 else if (dev->decoder == PHILIPS1)
352 pms_i2c_andor(dev, 0x42, 0x06, 0xcf, (pass & 0x03) << 4);
353 }
354
pms_antisnow(struct pms * dev,short snow)355 static void pms_antisnow(struct pms *dev, short snow)
356 {
357 if (dev->decoder == PHILIPS2)
358 pms_i2c_andor(dev, 0x8a, 0x06, 0xf3, (snow & 0x03) << 2);
359 else if (dev->decoder == PHILIPS1)
360 pms_i2c_andor(dev, 0x42, 0x06, 0xf3, (snow & 0x03) << 2);
361 }
362
pms_sharpness(struct pms * dev,short sharp)363 static void pms_sharpness(struct pms *dev, short sharp)
364 {
365 if (dev->decoder == PHILIPS2)
366 pms_i2c_andor(dev, 0x8a, 0x06, 0xfc, sharp & 0x03);
367 else if (dev->decoder == PHILIPS1)
368 pms_i2c_andor(dev, 0x42, 0x06, 0xfc, sharp & 0x03);
369 }
370
pms_chromaagc(struct pms * dev,short agc)371 static void pms_chromaagc(struct pms *dev, short agc)
372 {
373 if (dev->decoder == PHILIPS2)
374 pms_i2c_andor(dev, 0x8a, 0x0c, 0x9f, (agc & 0x03) << 5);
375 else if (dev->decoder == PHILIPS1)
376 pms_i2c_andor(dev, 0x42, 0x0c, 0x9f, (agc & 0x03) << 5);
377 }
378
pms_vertnoise(struct pms * dev,short noise)379 static void pms_vertnoise(struct pms *dev, short noise)
380 {
381 if (dev->decoder == PHILIPS2)
382 pms_i2c_andor(dev, 0x8a, 0x10, 0xfc, noise & 3);
383 else if (dev->decoder == PHILIPS1)
384 pms_i2c_andor(dev, 0x42, 0x10, 0xfc, noise & 3);
385 }
386
pms_forcecolour(struct pms * dev,short colour)387 static void pms_forcecolour(struct pms *dev, short colour)
388 {
389 if (dev->decoder == PHILIPS2)
390 pms_i2c_andor(dev, 0x8a, 0x0c, 0x7f, (colour & 1) << 7);
391 else if (dev->decoder == PHILIPS1)
392 pms_i2c_andor(dev, 0x42, 0x0c, 0x7, (colour & 1) << 7);
393 }
394
pms_antigamma(struct pms * dev,short gamma)395 static void pms_antigamma(struct pms *dev, short gamma)
396 {
397 if (dev->decoder == PHILIPS2)
398 pms_i2c_andor(dev, 0xb8, 0x00, 0x7f, (gamma & 1) << 7);
399 else if (dev->decoder == PHILIPS1)
400 pms_i2c_andor(dev, 0x42, 0x20, 0x7, (gamma & 1) << 7);
401 }
402
pms_prefilter(struct pms * dev,short filter)403 static void pms_prefilter(struct pms *dev, short filter)
404 {
405 if (dev->decoder == PHILIPS2)
406 pms_i2c_andor(dev, 0x8a, 0x06, 0xbf, (filter & 1) << 6);
407 else if (dev->decoder == PHILIPS1)
408 pms_i2c_andor(dev, 0x42, 0x06, 0xbf, (filter & 1) << 6);
409 }
410
pms_hfilter(struct pms * dev,short filter)411 static void pms_hfilter(struct pms *dev, short filter)
412 {
413 if (dev->decoder == PHILIPS2)
414 pms_i2c_andor(dev, 0xb8, 0x04, 0x1f, (filter & 7) << 5);
415 else if (dev->decoder == PHILIPS1)
416 pms_i2c_andor(dev, 0x42, 0x24, 0x1f, (filter & 7) << 5);
417 }
418
pms_vfilter(struct pms * dev,short filter)419 static void pms_vfilter(struct pms *dev, short filter)
420 {
421 if (dev->decoder == PHILIPS2)
422 pms_i2c_andor(dev, 0xb8, 0x08, 0x9f, (filter & 3) << 5);
423 else if (dev->decoder == PHILIPS1)
424 pms_i2c_andor(dev, 0x42, 0x28, 0x9f, (filter & 3) << 5);
425 }
426
pms_killcolour(struct pms * dev,short colour)427 static void pms_killcolour(struct pms *dev, short colour)
428 {
429 if (dev->decoder == PHILIPS2) {
430 pms_i2c_andor(dev, 0x8a, 0x08, 0x07, (colour & 0x1f) << 3);
431 pms_i2c_andor(dev, 0x8a, 0x09, 0x07, (colour & 0x1f) << 3);
432 } else if (dev->decoder == PHILIPS1) {
433 pms_i2c_andor(dev, 0x42, 0x08, 0x07, (colour & 0x1f) << 3);
434 pms_i2c_andor(dev, 0x42, 0x09, 0x07, (colour & 0x1f) << 3);
435 }
436 }
437
pms_chromagain(struct pms * dev,short chroma)438 static void pms_chromagain(struct pms *dev, short chroma)
439 {
440 if (dev->decoder == PHILIPS2)
441 pms_i2c_write(dev, 0x8a, 0x11, chroma);
442 else if (dev->decoder == PHILIPS1)
443 pms_i2c_write(dev, 0x42, 0x11, chroma);
444 }
445
446
pms_spacialcompl(struct pms * dev,short data)447 static void pms_spacialcompl(struct pms *dev, short data)
448 {
449 mvv_write(dev, 0x3b, data);
450 }
451
pms_spacialcomph(struct pms * dev,short data)452 static void pms_spacialcomph(struct pms *dev, short data)
453 {
454 mvv_write(dev, 0x3a, data);
455 }
456
pms_vstart(struct pms * dev,short start)457 static void pms_vstart(struct pms *dev, short start)
458 {
459 mvv_write(dev, 0x16, start);
460 mvv_write(dev, 0x17, (start >> 8) & 0x01);
461 }
462
463 #endif
464
pms_secamcross(struct pms * dev,short cross)465 static void pms_secamcross(struct pms *dev, short cross)
466 {
467 if (dev->decoder == PHILIPS2)
468 pms_i2c_andor(dev, 0x8a, 0x0f, 0xdf, (cross & 1) << 5);
469 else if (dev->decoder == PHILIPS1)
470 pms_i2c_andor(dev, 0x42, 0x0f, 0xdf, (cross & 1) << 5);
471 }
472
473
pms_swsense(struct pms * dev,short sense)474 static void pms_swsense(struct pms *dev, short sense)
475 {
476 if (dev->decoder == PHILIPS2) {
477 pms_i2c_write(dev, 0x8a, 0x0a, sense);
478 pms_i2c_write(dev, 0x8a, 0x0b, sense);
479 } else if (dev->decoder == PHILIPS1) {
480 pms_i2c_write(dev, 0x42, 0x0a, sense);
481 pms_i2c_write(dev, 0x42, 0x0b, sense);
482 }
483 }
484
485
pms_framerate(struct pms * dev,short frr)486 static void pms_framerate(struct pms *dev, short frr)
487 {
488 int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25;
489
490 if (frr == 0)
491 return;
492 fps = fps/frr;
493 mvv_write(dev, 0x14, 0x80 | fps);
494 mvv_write(dev, 0x15, 1);
495 }
496
pms_vert(struct pms * dev,u8 deciden,u8 decinum)497 static void pms_vert(struct pms *dev, u8 deciden, u8 decinum)
498 {
499 mvv_write(dev, 0x1c, deciden); /* Denominator */
500 mvv_write(dev, 0x1d, decinum); /* Numerator */
501 }
502
503 /*
504 * Turn 16bit ratios into best small ratio the chipset can grok
505 */
506
pms_vertdeci(struct pms * dev,unsigned short decinum,unsigned short deciden)507 static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden)
508 {
509 /* Knock it down by / 5 once */
510 if (decinum % 5 == 0) {
511 deciden /= 5;
512 decinum /= 5;
513 }
514 /*
515 * 3's
516 */
517 while (decinum % 3 == 0 && deciden % 3 == 0) {
518 deciden /= 3;
519 decinum /= 3;
520 }
521 /*
522 * 2's
523 */
524 while (decinum % 2 == 0 && deciden % 2 == 0) {
525 decinum /= 2;
526 deciden /= 2;
527 }
528 /*
529 * Fudgyify
530 */
531 while (deciden > 32) {
532 deciden /= 2;
533 decinum = (decinum + 1) / 2;
534 }
535 if (deciden == 32)
536 deciden--;
537 pms_vert(dev, deciden, decinum);
538 }
539
pms_horzdeci(struct pms * dev,short decinum,short deciden)540 static void pms_horzdeci(struct pms *dev, short decinum, short deciden)
541 {
542 if (decinum <= 512) {
543 if (decinum % 5 == 0) {
544 decinum /= 5;
545 deciden /= 5;
546 }
547 } else {
548 decinum = 512;
549 deciden = 640; /* 768 would be ideal */
550 }
551
552 while (((decinum | deciden) & 1) == 0) {
553 decinum >>= 1;
554 deciden >>= 1;
555 }
556 while (deciden > 32) {
557 deciden >>= 1;
558 decinum = (decinum + 1) >> 1;
559 }
560 if (deciden == 32)
561 deciden--;
562
563 mvv_write(dev, 0x24, 0x80 | deciden);
564 mvv_write(dev, 0x25, decinum);
565 }
566
pms_resolution(struct pms * dev,short width,short height)567 static void pms_resolution(struct pms *dev, short width, short height)
568 {
569 int fg_height;
570
571 fg_height = height;
572 if (fg_height > 280)
573 fg_height = 280;
574
575 mvv_write(dev, 0x18, fg_height);
576 mvv_write(dev, 0x19, fg_height >> 8);
577
578 if (dev->std & V4L2_STD_525_60) {
579 mvv_write(dev, 0x1a, 0xfc);
580 mvv_write(dev, 0x1b, 0x00);
581 if (height > fg_height)
582 pms_vertdeci(dev, 240, 240);
583 else
584 pms_vertdeci(dev, fg_height, 240);
585 } else {
586 mvv_write(dev, 0x1a, 0x1a);
587 mvv_write(dev, 0x1b, 0x01);
588 if (fg_height > 256)
589 pms_vertdeci(dev, 270, 270);
590 else
591 pms_vertdeci(dev, fg_height, 270);
592 }
593 mvv_write(dev, 0x12, 0);
594 mvv_write(dev, 0x13, MVVMEMORYWIDTH);
595 mvv_write(dev, 0x42, 0x00);
596 mvv_write(dev, 0x43, 0x00);
597 mvv_write(dev, 0x44, MVVMEMORYWIDTH);
598
599 mvv_write(dev, 0x22, width + 8);
600 mvv_write(dev, 0x23, (width + 8) >> 8);
601
602 if (dev->std & V4L2_STD_525_60)
603 pms_horzdeci(dev, width, 640);
604 else
605 pms_horzdeci(dev, width + 8, 768);
606
607 mvv_write(dev, 0x30, mvv_read(dev, 0x30) & 0xfe);
608 mvv_write(dev, 0x08, mvv_read(dev, 0x08) | 0x01);
609 mvv_write(dev, 0x01, mvv_read(dev, 0x01) & 0xfd);
610 mvv_write(dev, 0x32, 0x00);
611 mvv_write(dev, 0x33, MVVMEMORYWIDTH);
612 }
613
614
615 /*
616 * Set Input
617 */
618
pms_vcrinput(struct pms * dev,short input)619 static void pms_vcrinput(struct pms *dev, short input)
620 {
621 if (dev->decoder == PHILIPS2)
622 pms_i2c_andor(dev, 0x8a, 0x0d, 0x7f, (input & 1) << 7);
623 else if (dev->decoder == PHILIPS1)
624 pms_i2c_andor(dev, 0x42, 0x0d, 0x7f, (input & 1) << 7);
625 }
626
627
pms_capture(struct pms * dev,char __user * buf,int rgb555,int count)628 static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
629 {
630 int y;
631 int dw = 2 * dev->width;
632 char *tmp; /* using a temp buffer is faster than direct */
633 int cnt = 0;
634 int len = 0;
635 unsigned char r8 = 0x5; /* value for reg8 */
636
637 tmp = kmalloc(dw + 32, GFP_KERNEL);
638 if (!tmp)
639 return 0;
640
641 if (rgb555)
642 r8 |= 0x20; /* else use untranslated rgb = 565 */
643 mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
644
645 /* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
646
647 for (y = 0; y < dev->height; y++) {
648 writeb(0, dev->mem); /* synchronisiert neue Zeile */
649
650 /*
651 * This is in truth a fifo, be very careful as if you
652 * forgot this odd things will occur 8)
653 */
654
655 memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word */
656 cnt -= dev->height;
657 while (cnt <= 0) {
658 /*
659 * Don't copy too far
660 */
661 int dt = dw;
662 if (dt + len > count)
663 dt = count - len;
664 cnt += dev->height;
665 if (copy_to_user(buf, tmp + 32, dt))
666 return len ? len : -EFAULT;
667 buf += dt;
668 len += dt;
669 }
670 }
671 kfree(tmp);
672 return len;
673 }
674
675
676 /*
677 * Video4linux interfacing
678 */
679
pms_querycap(struct file * file,void * priv,struct v4l2_capability * vcap)680 static int pms_querycap(struct file *file, void *priv,
681 struct v4l2_capability *vcap)
682 {
683 struct pms *dev = video_drvdata(file);
684
685 strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver));
686 strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card));
687 snprintf(vcap->bus_info, sizeof(vcap->bus_info),
688 "ISA:%s", dev->v4l2_dev.name);
689 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
690 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
691 return 0;
692 }
693
pms_enum_input(struct file * file,void * fh,struct v4l2_input * vin)694 static int pms_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
695 {
696 static const char *inputs[4] = {
697 "Composite",
698 "S-Video",
699 "Composite (VCR)",
700 "S-Video (VCR)"
701 };
702
703 if (vin->index > 3)
704 return -EINVAL;
705 strlcpy(vin->name, inputs[vin->index], sizeof(vin->name));
706 vin->type = V4L2_INPUT_TYPE_CAMERA;
707 vin->audioset = 0;
708 vin->tuner = 0;
709 vin->std = V4L2_STD_ALL;
710 vin->status = 0;
711 return 0;
712 }
713
pms_g_input(struct file * file,void * fh,unsigned int * inp)714 static int pms_g_input(struct file *file, void *fh, unsigned int *inp)
715 {
716 struct pms *dev = video_drvdata(file);
717
718 *inp = dev->input;
719 return 0;
720 }
721
pms_s_input(struct file * file,void * fh,unsigned int inp)722 static int pms_s_input(struct file *file, void *fh, unsigned int inp)
723 {
724 struct pms *dev = video_drvdata(file);
725
726 if (inp > 3)
727 return -EINVAL;
728
729 dev->input = inp;
730 pms_videosource(dev, inp & 1);
731 pms_vcrinput(dev, inp >> 1);
732 return 0;
733 }
734
pms_g_std(struct file * file,void * fh,v4l2_std_id * std)735 static int pms_g_std(struct file *file, void *fh, v4l2_std_id *std)
736 {
737 struct pms *dev = video_drvdata(file);
738
739 *std = dev->std;
740 return 0;
741 }
742
pms_s_std(struct file * file,void * fh,v4l2_std_id std)743 static int pms_s_std(struct file *file, void *fh, v4l2_std_id std)
744 {
745 struct pms *dev = video_drvdata(file);
746 int ret = 0;
747
748 dev->std = std;
749 if (dev->std & V4L2_STD_NTSC) {
750 pms_framerate(dev, 30);
751 pms_secamcross(dev, 0);
752 pms_format(dev, 1);
753 } else if (dev->std & V4L2_STD_PAL) {
754 pms_framerate(dev, 25);
755 pms_secamcross(dev, 0);
756 pms_format(dev, 2);
757 } else if (dev->std & V4L2_STD_SECAM) {
758 pms_framerate(dev, 25);
759 pms_secamcross(dev, 1);
760 pms_format(dev, 2);
761 } else {
762 ret = -EINVAL;
763 }
764 /*
765 switch (v->mode) {
766 case VIDEO_MODE_AUTO:
767 pms_framerate(dev, 25);
768 pms_secamcross(dev, 0);
769 pms_format(dev, 0);
770 break;
771 }*/
772 return ret;
773 }
774
pms_s_ctrl(struct v4l2_ctrl * ctrl)775 static int pms_s_ctrl(struct v4l2_ctrl *ctrl)
776 {
777 struct pms *dev = container_of(ctrl->handler, struct pms, hdl);
778 int ret = 0;
779
780 switch (ctrl->id) {
781 case V4L2_CID_BRIGHTNESS:
782 pms_brightness(dev, ctrl->val);
783 break;
784 case V4L2_CID_CONTRAST:
785 pms_contrast(dev, ctrl->val);
786 break;
787 case V4L2_CID_SATURATION:
788 pms_saturation(dev, ctrl->val);
789 break;
790 case V4L2_CID_HUE:
791 pms_hue(dev, ctrl->val);
792 break;
793 default:
794 ret = -EINVAL;
795 break;
796 }
797 return ret;
798 }
799
pms_g_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)800 static int pms_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
801 {
802 struct pms *dev = video_drvdata(file);
803 struct v4l2_pix_format *pix = &fmt->fmt.pix;
804
805 pix->width = dev->width;
806 pix->height = dev->height;
807 pix->pixelformat = dev->width == 15 ?
808 V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB565;
809 pix->field = V4L2_FIELD_NONE;
810 pix->bytesperline = 2 * dev->width;
811 pix->sizeimage = 2 * dev->width * dev->height;
812 /* Just a guess */
813 pix->colorspace = V4L2_COLORSPACE_SRGB;
814 return 0;
815 }
816
pms_try_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)817 static int pms_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
818 {
819 struct v4l2_pix_format *pix = &fmt->fmt.pix;
820
821 if (pix->height < 16 || pix->height > 480)
822 return -EINVAL;
823 if (pix->width < 16 || pix->width > 640)
824 return -EINVAL;
825 if (pix->pixelformat != V4L2_PIX_FMT_RGB555 &&
826 pix->pixelformat != V4L2_PIX_FMT_RGB565)
827 return -EINVAL;
828 pix->field = V4L2_FIELD_NONE;
829 pix->bytesperline = 2 * pix->width;
830 pix->sizeimage = 2 * pix->width * pix->height;
831 /* Just a guess */
832 pix->colorspace = V4L2_COLORSPACE_SRGB;
833 return 0;
834 }
835
pms_s_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)836 static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
837 {
838 struct pms *dev = video_drvdata(file);
839 struct v4l2_pix_format *pix = &fmt->fmt.pix;
840 int ret = pms_try_fmt_vid_cap(file, fh, fmt);
841
842 if (ret)
843 return ret;
844 dev->width = pix->width;
845 dev->height = pix->height;
846 dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16;
847 pms_resolution(dev, dev->width, dev->height);
848 /* Ok we figured out what to use from our wide choice */
849 return 0;
850 }
851
pms_enum_fmt_vid_cap(struct file * file,void * fh,struct v4l2_fmtdesc * fmt)852 static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
853 {
854 static struct v4l2_fmtdesc formats[] = {
855 { 0, 0, 0,
856 "RGB 5:5:5", V4L2_PIX_FMT_RGB555,
857 { 0, 0, 0, 0 }
858 },
859 { 1, 0, 0,
860 "RGB 5:6:5", V4L2_PIX_FMT_RGB565,
861 { 0, 0, 0, 0 }
862 },
863 };
864 enum v4l2_buf_type type = fmt->type;
865
866 if (fmt->index > 1)
867 return -EINVAL;
868
869 *fmt = formats[fmt->index];
870 fmt->type = type;
871 return 0;
872 }
873
pms_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)874 static ssize_t pms_read(struct file *file, char __user *buf,
875 size_t count, loff_t *ppos)
876 {
877 struct pms *dev = video_drvdata(file);
878 int len;
879
880 len = pms_capture(dev, buf, (dev->depth == 15), count);
881 return len;
882 }
883
pms_poll(struct file * file,struct poll_table_struct * wait)884 static unsigned int pms_poll(struct file *file, struct poll_table_struct *wait)
885 {
886 struct v4l2_fh *fh = file->private_data;
887 unsigned int res = POLLIN | POLLRDNORM;
888
889 if (v4l2_event_pending(fh))
890 res |= POLLPRI;
891 poll_wait(file, &fh->wait, wait);
892 return res;
893 }
894
895 static const struct v4l2_file_operations pms_fops = {
896 .owner = THIS_MODULE,
897 .open = v4l2_fh_open,
898 .release = v4l2_fh_release,
899 .poll = pms_poll,
900 .unlocked_ioctl = video_ioctl2,
901 .read = pms_read,
902 };
903
904 static const struct v4l2_ioctl_ops pms_ioctl_ops = {
905 .vidioc_querycap = pms_querycap,
906 .vidioc_g_input = pms_g_input,
907 .vidioc_s_input = pms_s_input,
908 .vidioc_enum_input = pms_enum_input,
909 .vidioc_g_std = pms_g_std,
910 .vidioc_s_std = pms_s_std,
911 .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap,
912 .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap,
913 .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap,
914 .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap,
915 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
916 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
917 };
918
919 /*
920 * Probe for and initialise the Mediavision PMS
921 */
922
init_mediavision(struct pms * dev)923 static int init_mediavision(struct pms *dev)
924 {
925 int idec, decst;
926 int i;
927 static const unsigned char i2c_defs[] = {
928 0x4c, 0x30, 0x00, 0xe8,
929 0xb6, 0xe2, 0x00, 0x00,
930 0xff, 0xff, 0x00, 0x00,
931 0x00, 0x00, 0x78, 0x98,
932 0x00, 0x00, 0x00, 0x00,
933 0x34, 0x0a, 0xf4, 0xce,
934 0xe4
935 };
936
937 dev->mem = ioremap(mem_base, 0x800);
938 if (!dev->mem)
939 return -ENOMEM;
940
941 if (!request_region(0x9a01, 1, "Mediavision PMS config")) {
942 printk(KERN_WARNING "mediavision: unable to detect: 0x9a01 in use.\n");
943 iounmap(dev->mem);
944 return -EBUSY;
945 }
946 if (!request_region(dev->io, 3, "Mediavision PMS")) {
947 printk(KERN_WARNING "mediavision: I/O port %d in use.\n", dev->io);
948 release_region(0x9a01, 1);
949 iounmap(dev->mem);
950 return -EBUSY;
951 }
952 outb(0xb8, 0x9a01); /* Unlock */
953 outb(dev->io >> 4, 0x9a01); /* Set IO port */
954
955
956 decst = pms_i2c_stat(dev, 0x43);
957
958 if (decst != -1)
959 idec = 2;
960 else if (pms_i2c_stat(dev, 0xb9) != -1)
961 idec = 3;
962 else if (pms_i2c_stat(dev, 0x8b) != -1)
963 idec = 1;
964 else
965 idec = 0;
966
967 printk(KERN_INFO "PMS type is %d\n", idec);
968 if (idec == 0) {
969 release_region(dev->io, 3);
970 release_region(0x9a01, 1);
971 iounmap(dev->mem);
972 return -ENODEV;
973 }
974
975 /*
976 * Ok we have a PMS of some sort
977 */
978
979 mvv_write(dev, 0x04, mem_base >> 12); /* Set the memory area */
980
981 /* Ok now load the defaults */
982
983 for (i = 0; i < 0x19; i++) {
984 if (i2c_defs[i] == 0xff)
985 pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00);
986 else
987 pms_i2c_write(dev, 0x8a, i, i2c_defs[i]);
988 }
989
990 pms_i2c_write(dev, 0xb8, 0x00, 0x12);
991 pms_i2c_write(dev, 0xb8, 0x04, 0x00);
992 pms_i2c_write(dev, 0xb8, 0x07, 0x00);
993 pms_i2c_write(dev, 0xb8, 0x08, 0x00);
994 pms_i2c_write(dev, 0xb8, 0x09, 0xff);
995 pms_i2c_write(dev, 0xb8, 0x0a, 0x00);
996 pms_i2c_write(dev, 0xb8, 0x0b, 0x10);
997 pms_i2c_write(dev, 0xb8, 0x10, 0x03);
998
999 mvv_write(dev, 0x01, 0x00);
1000 mvv_write(dev, 0x05, 0xa0);
1001 mvv_write(dev, 0x08, 0x25);
1002 mvv_write(dev, 0x09, 0x00);
1003 mvv_write(dev, 0x0a, 0x20 | MVVMEMORYWIDTH);
1004
1005 mvv_write(dev, 0x10, 0x02);
1006 mvv_write(dev, 0x1e, 0x0c);
1007 mvv_write(dev, 0x1f, 0x03);
1008 mvv_write(dev, 0x26, 0x06);
1009
1010 mvv_write(dev, 0x2b, 0x00);
1011 mvv_write(dev, 0x2c, 0x20);
1012 mvv_write(dev, 0x2d, 0x00);
1013 mvv_write(dev, 0x2f, 0x70);
1014 mvv_write(dev, 0x32, 0x00);
1015 mvv_write(dev, 0x33, MVVMEMORYWIDTH);
1016 mvv_write(dev, 0x34, 0x00);
1017 mvv_write(dev, 0x35, 0x00);
1018 mvv_write(dev, 0x3a, 0x80);
1019 mvv_write(dev, 0x3b, 0x10);
1020 mvv_write(dev, 0x20, 0x00);
1021 mvv_write(dev, 0x21, 0x00);
1022 mvv_write(dev, 0x30, 0x22);
1023 return 0;
1024 }
1025
1026 /*
1027 * Initialization and module stuff
1028 */
1029
1030 #ifndef MODULE
1031 static int enable;
1032 module_param(enable, int, 0);
1033 #endif
1034
1035 static const struct v4l2_ctrl_ops pms_ctrl_ops = {
1036 .s_ctrl = pms_s_ctrl,
1037 };
1038
pms_probe(struct device * pdev,unsigned int card)1039 static int pms_probe(struct device *pdev, unsigned int card)
1040 {
1041 struct pms *dev;
1042 struct v4l2_device *v4l2_dev;
1043 struct v4l2_ctrl_handler *hdl;
1044 int res;
1045
1046 #ifndef MODULE
1047 if (!enable) {
1048 pr_err("PMS: not enabled, use pms.enable=1 to probe\n");
1049 return -ENODEV;
1050 }
1051 #endif
1052
1053 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1054 if (dev == NULL)
1055 return -ENOMEM;
1056
1057 dev->decoder = PHILIPS2;
1058 dev->io = io_port;
1059 dev->data = io_port + 1;
1060 v4l2_dev = &dev->v4l2_dev;
1061 hdl = &dev->hdl;
1062
1063 res = v4l2_device_register(pdev, v4l2_dev);
1064 if (res < 0) {
1065 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
1066 goto free_dev;
1067 }
1068 v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.05\n");
1069
1070 res = init_mediavision(dev);
1071 if (res) {
1072 v4l2_err(v4l2_dev, "Board not found.\n");
1073 goto free_io;
1074 }
1075
1076 v4l2_ctrl_handler_init(hdl, 4);
1077 v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
1078 V4L2_CID_BRIGHTNESS, 0, 255, 1, 139);
1079 v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
1080 V4L2_CID_CONTRAST, 0, 255, 1, 70);
1081 v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
1082 V4L2_CID_SATURATION, 0, 255, 1, 64);
1083 v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
1084 V4L2_CID_HUE, 0, 255, 1, 0);
1085 if (hdl->error) {
1086 res = hdl->error;
1087 goto free_hdl;
1088 }
1089
1090 mutex_init(&dev->lock);
1091 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
1092 dev->vdev.v4l2_dev = v4l2_dev;
1093 dev->vdev.ctrl_handler = hdl;
1094 dev->vdev.fops = &pms_fops;
1095 dev->vdev.ioctl_ops = &pms_ioctl_ops;
1096 dev->vdev.release = video_device_release_empty;
1097 dev->vdev.lock = &dev->lock;
1098 dev->vdev.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1099 video_set_drvdata(&dev->vdev, dev);
1100 dev->std = V4L2_STD_NTSC_M;
1101 dev->height = 240;
1102 dev->width = 320;
1103 dev->depth = 16;
1104 pms_swsense(dev, 75);
1105 pms_resolution(dev, 320, 240);
1106 pms_videosource(dev, 0);
1107 pms_vcrinput(dev, 0);
1108 v4l2_ctrl_handler_setup(hdl);
1109 res = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr);
1110 if (res >= 0)
1111 return 0;
1112
1113 free_hdl:
1114 v4l2_ctrl_handler_free(hdl);
1115 v4l2_device_unregister(&dev->v4l2_dev);
1116 free_io:
1117 release_region(dev->io, 3);
1118 release_region(0x9a01, 1);
1119 iounmap(dev->mem);
1120 free_dev:
1121 kfree(dev);
1122 return res;
1123 }
1124
pms_remove(struct device * pdev,unsigned int card)1125 static int pms_remove(struct device *pdev, unsigned int card)
1126 {
1127 struct pms *dev = dev_get_drvdata(pdev);
1128
1129 video_unregister_device(&dev->vdev);
1130 v4l2_ctrl_handler_free(&dev->hdl);
1131 release_region(dev->io, 3);
1132 release_region(0x9a01, 1);
1133 iounmap(dev->mem);
1134 return 0;
1135 }
1136
1137 static struct isa_driver pms_driver = {
1138 .probe = pms_probe,
1139 .remove = pms_remove,
1140 .driver = {
1141 .name = "pms",
1142 },
1143 };
1144
pms_init(void)1145 static int __init pms_init(void)
1146 {
1147 return isa_register_driver(&pms_driver, 1);
1148 }
1149
pms_exit(void)1150 static void __exit pms_exit(void)
1151 {
1152 isa_unregister_driver(&pms_driver);
1153 }
1154
1155 module_init(pms_init);
1156 module_exit(pms_exit);
1157