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