[media] Stop using linux/version.h on most video drivers
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / media / video / pms.c
CommitLineData
1da177e4
LT
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.
d9b01449
AC
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...
d56410e0 15 *
1da177e4 16 * Changes:
feba2f81
HV
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
1da177e4
LT
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>
1da177e4
LT
28#include <linux/mm.h>
29#include <linux/ioport.h>
30#include <linux/init.h>
feba2f81 31#include <linux/mutex.h>
262ab9ac 32#include <linux/uaccess.h>
1da177e4 33#include <asm/io.h>
feba2f81
HV
34
35#include <linux/videodev2.h>
5e87efa3 36#include <media/v4l2-common.h>
35ea11ff 37#include <media/v4l2-ioctl.h>
1ce7981b 38#include <media/v4l2-device.h>
1da177e4 39
1ce7981b 40MODULE_LICENSE("GPL");
1990d50b 41MODULE_VERSION("0.0.4");
1da177e4
LT
42
43#define MOTOROLA 1
feba2f81 44#define PHILIPS2 2 /* SAA7191 */
1da177e4
LT
45#define PHILIPS1 3
46#define MVVMEMORYWIDTH 0x40 /* 512 bytes */
47
1ce7981b 48struct i2c_info {
1da177e4
LT
49 u8 slave;
50 u8 sub;
51 u8 data;
52 u8 hits;
53};
54
1ce7981b
HV
55struct pms {
56 struct v4l2_device v4l2_dev;
57 struct video_device vdev;
1ce7981b
HV
58 int height;
59 int width;
feba2f81
HV
60 int depth;
61 int input;
62 s32 brightness, saturation, hue, contrast;
1ce7981b
HV
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 */
feba2f81 69 v4l2_std_id std;
1ce7981b
HV
70 int io;
71 int data;
72 void __iomem *mem;
73};
1da177e4 74
1ce7981b 75static struct pms pms_card;
1da177e4
LT
76
77/*
78 * I/O ports and Shared Memory
79 */
d56410e0 80
1ce7981b
HV
81static int io_port = 0x250;
82module_param(io_port, int, 0);
83
84static int mem_base = 0xc8000;
85module_param(mem_base, int, 0);
1da177e4 86
1ce7981b
HV
87static int video_nr = -1;
88module_param(video_nr, int, 0);
d56410e0 89
1da177e4 90
1ce7981b 91static inline void mvv_write(struct pms *dev, u8 index, u8 value)
1da177e4 92{
1ce7981b 93 outw(index | (value << 8), dev->io);
1da177e4
LT
94}
95
1ce7981b 96static inline u8 mvv_read(struct pms *dev, u8 index)
1da177e4 97{
1ce7981b
HV
98 outb(index, dev->io);
99 return inb(dev->data);
1da177e4
LT
100}
101
1ce7981b 102static int pms_i2c_stat(struct pms *dev, u8 slave)
1da177e4 103{
1ce7981b 104 int counter = 0;
1da177e4 105 int i;
d56410e0 106
1ce7981b 107 outb(0x28, dev->io);
d56410e0 108
1ce7981b
HV
109 while ((inb(dev->data) & 0x01) == 0)
110 if (counter++ == 256)
1da177e4
LT
111 break;
112
1ce7981b
HV
113 while ((inb(dev->data) & 0x01) != 0)
114 if (counter++ == 256)
1da177e4 115 break;
d56410e0 116
1ce7981b 117 outb(slave, dev->io);
d56410e0 118
1ce7981b
HV
119 counter = 0;
120 while ((inb(dev->data) & 0x01) == 0)
121 if (counter++ == 256)
1da177e4
LT
122 break;
123
1ce7981b
HV
124 while ((inb(dev->data) & 0x01) != 0)
125 if (counter++ == 256)
1da177e4 126 break;
d56410e0 127
1ce7981b
HV
128 for (i = 0; i < 12; i++) {
129 char st = inb(dev->data);
130
131 if ((st & 2) != 0)
1da177e4 132 return -1;
1ce7981b 133 if ((st & 1) == 0)
1da177e4
LT
134 break;
135 }
1ce7981b
HV
136 outb(0x29, dev->io);
137 return inb(dev->data);
1da177e4
LT
138}
139
1ce7981b 140static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data)
1da177e4 141{
1ce7981b 142 int skip = 0;
1da177e4
LT
143 int count;
144 int i;
d56410e0 145
1ce7981b
HV
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;
1da177e4
LT
153 }
154 }
d56410e0 155
1ce7981b
HV
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++;
1da177e4 161 }
d56410e0 162
1ce7981b 163 if (skip)
1da177e4 164 return 0;
d56410e0 165
1ce7981b
HV
166 mvv_write(dev, 0x29, sub);
167 mvv_write(dev, 0x2A, data);
168 mvv_write(dev, 0x28, slave);
d56410e0 169
1ce7981b 170 outb(0x28, dev->io);
d56410e0 171
1ce7981b
HV
172 count = 0;
173 while ((inb(dev->data) & 1) == 0)
174 if (count > 255)
1da177e4 175 break;
1ce7981b
HV
176 while ((inb(dev->data) & 1) != 0)
177 if (count > 255)
1da177e4 178 break;
d56410e0 179
1ce7981b 180 count = inb(dev->data);
d56410e0 181
1ce7981b 182 if (count & 2)
1da177e4
LT
183 return -1;
184 return count;
185}
186
1ce7981b 187static int pms_i2c_read(struct pms *dev, int slave, int sub)
1da177e4 188{
1ce7981b
HV
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;
1da177e4
LT
194 }
195 return 0;
196}
197
198
1ce7981b 199static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or)
1da177e4 200{
d56410e0
MCC
201 u8 tmp;
202
1ce7981b
HV
203 tmp = pms_i2c_read(dev, slave, sub);
204 tmp = (tmp & and) | or;
205 pms_i2c_write(dev, slave, sub, tmp);
1da177e4
LT
206}
207
208/*
209 * Control functions
210 */
d56410e0 211
1da177e4 212
1ce7981b 213static void pms_videosource(struct pms *dev, short source)
1da177e4 214{
feba2f81
HV
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. */
1da177e4
LT
228}
229
1ce7981b 230static void pms_hue(struct pms *dev, short hue)
1da177e4 231{
1ce7981b
HV
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;
1da177e4
LT
242 }
243}
244
feba2f81 245static void pms_saturation(struct pms *dev, short sat)
1da177e4 246{
1ce7981b
HV
247 switch (dev->decoder) {
248 case MOTOROLA:
feba2f81 249 pms_i2c_write(dev, 0x8a, 0x00, sat);
1ce7981b
HV
250 break;
251 case PHILIPS1:
feba2f81 252 pms_i2c_write(dev, 0x42, 0x12, sat);
1ce7981b 253 break;
1da177e4
LT
254 }
255}
d56410e0
MCC
256
257
1ce7981b 258static void pms_contrast(struct pms *dev, short contrast)
1da177e4 259{
1ce7981b
HV
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;
1da177e4
LT
267 }
268}
269
1ce7981b 270static void pms_brightness(struct pms *dev, short brightness)
1da177e4 271{
1ce7981b
HV
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;
1da177e4
LT
281 }
282}
283
284
1ce7981b 285static void pms_format(struct pms *dev, short format)
1da177e4
LT
286{
287 int target;
d56410e0 288
1ce7981b
HV
289 dev->standard = format;
290
291 if (dev->decoder == PHILIPS1)
292 target = 0x42;
293 else if (dev->decoder == PHILIPS2)
294 target = 0x8a;
1da177e4
LT
295 else
296 return;
d56410e0 297
1ce7981b
HV
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;
1da177e4
LT
315 }
316}
317
318#ifdef FOR_FUTURE_EXPANSION
319
320/*
321 * These features of the PMS card are not currently exposes. They
d56410e0 322 * could become a private v4l ioctl for PMSCONFIG or somesuch if
1da177e4
LT
323 * people need it. We also don't yet use the PMS interrupt.
324 */
325
1ce7981b 326static void pms_hstart(struct pms *dev, short start)
1da177e4 327{
1ce7981b
HV
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;
1da177e4
LT
337 }
338}
339
340/*
341 * Bandpass filters
342 */
d56410e0 343
1ce7981b 344static void pms_bandpass(struct pms *dev, short pass)
1da177e4 345{
1ce7981b
HV
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);
1da177e4
LT
350}
351
1ce7981b 352static void pms_antisnow(struct pms *dev, short snow)
1da177e4 353{
1ce7981b
HV
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);
1da177e4
LT
358}
359
1ce7981b 360static void pms_sharpness(struct pms *dev, short sharp)
1da177e4 361{
1ce7981b
HV
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);
1da177e4
LT
366}
367
1ce7981b 368static void pms_chromaagc(struct pms *dev, short agc)
1da177e4 369{
1ce7981b
HV
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);
1da177e4
LT
374}
375
1ce7981b 376static void pms_vertnoise(struct pms *dev, short noise)
1da177e4 377{
1ce7981b
HV
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);
1da177e4
LT
382}
383
1ce7981b 384static void pms_forcecolour(struct pms *dev, short colour)
1da177e4 385{
1ce7981b
HV
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);
1da177e4
LT
390}
391
1ce7981b 392static void pms_antigamma(struct pms *dev, short gamma)
1da177e4 393{
1ce7981b
HV
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);
1da177e4
LT
398}
399
1ce7981b 400static void pms_prefilter(struct pms *dev, short filter)
1da177e4 401{
1ce7981b
HV
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);
1da177e4
LT
406}
407
1ce7981b 408static void pms_hfilter(struct pms *dev, short filter)
1da177e4 409{
1ce7981b
HV
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);
1da177e4
LT
414}
415
1ce7981b 416static void pms_vfilter(struct pms *dev, short filter)
1da177e4 417{
1ce7981b
HV
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);
1da177e4
LT
422}
423
1ce7981b 424static void pms_killcolour(struct pms *dev, short colour)
1da177e4 425{
1ce7981b
HV
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);
1da177e4
LT
432 }
433}
434
1ce7981b 435static void pms_chromagain(struct pms *dev, short chroma)
1da177e4 436{
1ce7981b
HV
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);
1da177e4
LT
441}
442
443
1ce7981b 444static void pms_spacialcompl(struct pms *dev, short data)
1da177e4 445{
1ce7981b 446 mvv_write(dev, 0x3b, data);
1da177e4
LT
447}
448
1ce7981b 449static void pms_spacialcomph(struct pms *dev, short data)
1da177e4 450{
1ce7981b 451 mvv_write(dev, 0x3a, data);
1da177e4
LT
452}
453
1ce7981b 454static void pms_vstart(struct pms *dev, short start)
1da177e4 455{
1ce7981b
HV
456 mvv_write(dev, 0x16, start);
457 mvv_write(dev, 0x17, (start >> 8) & 0x01);
1da177e4
LT
458}
459
460#endif
461
1ce7981b 462static void pms_secamcross(struct pms *dev, short cross)
1da177e4 463{
1ce7981b
HV
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);
1da177e4
LT
468}
469
470
1ce7981b 471static void pms_swsense(struct pms *dev, short sense)
1da177e4 472{
1ce7981b
HV
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);
1da177e4
LT
479 }
480}
481
482
1ce7981b 483static void pms_framerate(struct pms *dev, short frr)
1da177e4 484{
feba2f81 485 int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25;
1ce7981b
HV
486
487 if (frr == 0)
1da177e4 488 return;
1ce7981b
HV
489 fps = fps/frr;
490 mvv_write(dev, 0x14, 0x80 | fps);
491 mvv_write(dev, 0x15, 1);
1da177e4
LT
492}
493
1ce7981b 494static void pms_vert(struct pms *dev, u8 deciden, u8 decinum)
1da177e4 495{
1ce7981b
HV
496 mvv_write(dev, 0x1c, deciden); /* Denominator */
497 mvv_write(dev, 0x1d, decinum); /* Numerator */
1da177e4
LT
498}
499
500/*
501 * Turn 16bit ratios into best small ratio the chipset can grok
502 */
d56410e0 503
1ce7981b 504static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden)
1da177e4 505{
1ce7981b
HV
506 /* Knock it down by / 5 once */
507 if (decinum % 5 == 0) {
508 deciden /= 5;
509 decinum /= 5;
1da177e4
LT
510 }
511 /*
512 * 3's
513 */
1ce7981b
HV
514 while (decinum % 3 == 0 && deciden % 3 == 0) {
515 deciden /= 3;
516 decinum /= 3;
1da177e4
LT
517 }
518 /*
519 * 2's
520 */
1ce7981b
HV
521 while (decinum % 2 == 0 && deciden % 2 == 0) {
522 decinum /= 2;
523 deciden /= 2;
1da177e4
LT
524 }
525 /*
526 * Fudgyify
527 */
1ce7981b
HV
528 while (deciden > 32) {
529 deciden /= 2;
530 decinum = (decinum + 1) / 2;
1da177e4 531 }
1ce7981b 532 if (deciden == 32)
1da177e4 533 deciden--;
1ce7981b 534 pms_vert(dev, deciden, decinum);
1da177e4
LT
535}
536
1ce7981b 537static void pms_horzdeci(struct pms *dev, short decinum, short deciden)
1da177e4 538{
1ce7981b
HV
539 if (decinum <= 512) {
540 if (decinum % 5 == 0) {
541 decinum /= 5;
542 deciden /= 5;
1da177e4 543 }
1ce7981b
HV
544 } else {
545 decinum = 512;
546 deciden = 640; /* 768 would be ideal */
1da177e4 547 }
d56410e0 548
1ce7981b
HV
549 while (((decinum | deciden) & 1) == 0) {
550 decinum >>= 1;
551 deciden >>= 1;
1da177e4 552 }
1ce7981b
HV
553 while (deciden > 32) {
554 deciden >>= 1;
555 decinum = (decinum + 1) >> 1;
1da177e4 556 }
1ce7981b 557 if (deciden == 32)
1da177e4 558 deciden--;
d56410e0 559
1ce7981b
HV
560 mvv_write(dev, 0x24, 0x80 | deciden);
561 mvv_write(dev, 0x25, decinum);
1da177e4
LT
562}
563
1ce7981b 564static void pms_resolution(struct pms *dev, short width, short height)
1da177e4
LT
565{
566 int fg_height;
d56410e0 567
1ce7981b
HV
568 fg_height = height;
569 if (fg_height > 280)
570 fg_height = 280;
d56410e0 571
1ce7981b
HV
572 mvv_write(dev, 0x18, fg_height);
573 mvv_write(dev, 0x19, fg_height >> 8);
d56410e0 574
feba2f81 575 if (dev->std & V4L2_STD_525_60) {
1ce7981b
HV
576 mvv_write(dev, 0x1a, 0xfc);
577 mvv_write(dev, 0x1b, 0x00);
578 if (height > fg_height)
579 pms_vertdeci(dev, 240, 240);
1da177e4 580 else
1ce7981b
HV
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);
1da177e4 587 else
1ce7981b 588 pms_vertdeci(dev, fg_height, 270);
1da177e4 589 }
1ce7981b
HV
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);
d56410e0 595
1ce7981b
HV
596 mvv_write(dev, 0x22, width + 8);
597 mvv_write(dev, 0x23, (width + 8) >> 8);
1da177e4 598
feba2f81 599 if (dev->std & V4L2_STD_525_60)
1ce7981b 600 pms_horzdeci(dev, width, 640);
1da177e4 601 else
1ce7981b 602 pms_horzdeci(dev, width + 8, 768);
1da177e4 603
1ce7981b
HV
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);
1da177e4
LT
609}
610
611
612/*
613 * Set Input
614 */
d56410e0 615
1ce7981b 616static void pms_vcrinput(struct pms *dev, short input)
1da177e4 617{
1ce7981b
HV
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);
1da177e4
LT
622}
623
624
1ce7981b 625static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
1da177e4
LT
626{
627 int y;
1ce7981b
HV
628 int dw = 2 * dev->width;
629 char tmp[dw + 32]; /* using a temp buffer is faster than direct */
1da177e4 630 int cnt = 0;
1ce7981b 631 int len = 0;
1da177e4
LT
632 unsigned char r8 = 0x5; /* value for reg8 */
633
634 if (rgb555)
635 r8 |= 0x20; /* else use untranslated rgb = 565 */
1ce7981b 636 mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
1da177e4
LT
637
638/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
d56410e0 639
1ce7981b
HV
640 for (y = 0; y < dev->height; y++) {
641 writeb(0, dev->mem); /* synchronisiert neue Zeile */
d56410e0 642
1da177e4
LT
643 /*
644 * This is in truth a fifo, be very careful as if you
645 * forgot this odd things will occur 8)
646 */
d56410e0 647
1ce7981b 648 memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word */
1da177e4 649 cnt -= dev->height;
1ce7981b 650 while (cnt <= 0) {
1da177e4
LT
651 /*
652 * Don't copy too far
653 */
1ce7981b
HV
654 int dt = dw;
655 if (dt + len > count)
656 dt = count - len;
1da177e4 657 cnt += dev->height;
1ce7981b 658 if (copy_to_user(buf, tmp + 32, dt))
1da177e4 659 return len ? len : -EFAULT;
d56410e0 660 buf += dt;
1da177e4
LT
661 len += dt;
662 }
663 }
664 return len;
665}
666
667
668/*
669 * Video4linux interfacing
670 */
671
feba2f81
HV
672static int pms_querycap(struct file *file, void *priv,
673 struct v4l2_capability *vcap)
1da177e4 674{
1ce7981b
HV
675 struct pms *dev = video_drvdata(file);
676
feba2f81
HV
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));
feba2f81
HV
680 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
681 return 0;
682}
1ce7981b 683
feba2f81
HV
684static 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 };
1ce7981b 692
feba2f81
HV
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}
1ce7981b 703
feba2f81
HV
704static int pms_g_input(struct file *file, void *fh, unsigned int *inp)
705{
706 struct pms *dev = video_drvdata(file);
1ce7981b 707
feba2f81
HV
708 *inp = dev->input;
709 return 0;
710}
711
712static 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
727static 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
735static 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;
1ce7981b 756 }
feba2f81
HV
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
769static 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);
1ce7981b 781 }
feba2f81
HV
782 return -EINVAL;
783}
1ce7981b 784
feba2f81
HV
785static 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;
1ce7981b 807 }
feba2f81
HV
808 return ret;
809}
810
811static 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;
1ce7981b 835 default:
feba2f81
HV
836 ret = -EINVAL;
837 break;
1da177e4 838 }
feba2f81
HV
839 mutex_unlock(&dev->lock);
840 return ret;
841}
842
843static 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
860static 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;
1da177e4
LT
876 return 0;
877}
878
feba2f81 879static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
1da177e4 880{
feba2f81
HV
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
897static 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;
1da177e4
LT
917}
918
919static ssize_t pms_read(struct file *file, char __user *buf,
920 size_t count, loff_t *ppos)
921{
1ce7981b 922 struct pms *dev = video_drvdata(file);
1da177e4 923 int len;
d56410e0 924
1ce7981b 925 mutex_lock(&dev->lock);
feba2f81 926 len = pms_capture(dev, buf, (dev->depth == 15), count);
1ce7981b 927 mutex_unlock(&dev->lock);
1da177e4
LT
928 return len;
929}
930
bec43661 931static const struct v4l2_file_operations pms_fops = {
1da177e4 932 .owner = THIS_MODULE,
61df3c9b 933 .unlocked_ioctl = video_ioctl2,
1da177e4 934 .read = pms_read,
1da177e4
LT
935};
936
feba2f81
HV
937static 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};
1da177e4
LT
952
953/*
954 * Probe for and initialise the Mediavision PMS
955 */
d56410e0 956
1ce7981b 957static int init_mediavision(struct pms *dev)
1da177e4
LT
958{
959 int id;
960 int idec, decst;
961 int i;
1ce7981b
HV
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
1da177e4
LT
970 };
971
1ce7981b
HV
972 dev->mem = ioremap(mem_base, 0x800);
973 if (!dev->mem)
1da177e4 974 return -ENOMEM;
d56410e0 975
1ce7981b
HV
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);
1da177e4
LT
979 return -EBUSY;
980 }
1ce7981b
HV
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);
1da177e4
LT
985 return -EBUSY;
986 }
1ce7981b
HV
987 outb(0xb8, 0x9a01); /* Unlock */
988 outb(dev->io >> 4, 0x9a01); /* Set IO port */
d56410e0
MCC
989
990
1ce7981b
HV
991 id = mvv_read(dev, 3);
992 decst = pms_i2c_stat(dev, 0x43);
d56410e0 993
1ce7981b
HV
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;
d56410e0 1000 else
1ce7981b 1001 idec = 0;
1da177e4
LT
1002
1003 printk(KERN_INFO "PMS type is %d\n", idec);
1ce7981b
HV
1004 if (idec == 0) {
1005 release_region(dev->io, 3);
1006 release_region(0x9a01, 1);
1007 iounmap(dev->mem);
1da177e4
LT
1008 return -ENODEV;
1009 }
1010
1011 /*
1012 * Ok we have a PMS of some sort
1013 */
d56410e0 1014
1ce7981b 1015 mvv_write(dev, 0x04, mem_base >> 12); /* Set the memory area */
d56410e0 1016
1da177e4 1017 /* Ok now load the defaults */
d56410e0 1018
1ce7981b
HV
1019 for (i = 0; i < 0x19; i++) {
1020 if (i2c_defs[i] == 0xff)
1021 pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00);
1da177e4 1022 else
1ce7981b 1023 pms_i2c_write(dev, 0x8a, i, i2c_defs[i]);
1da177e4 1024 }
d56410e0 1025
1ce7981b
HV
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);
1da177e4
LT
1059 return 0;
1060}
1061
1062/*
1063 * Initialization and module stuff
1064 */
d56410e0 1065
b54ff939
RH
1066#ifndef MODULE
1067static int enable;
1068module_param(enable, int, 0);
1069#endif
1070
1ce7981b 1071static int __init pms_init(void)
1da177e4 1072{
1ce7981b
HV
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");
d56410e0 1080
b54ff939
RH
1081#ifndef MODULE
1082 if (!enable) {
1ce7981b
HV
1083 v4l2_err(v4l2_dev,
1084 "PMS: not enabled, use pms.enable=1 to probe\n");
b54ff939
RH
1085 return -ENODEV;
1086 }
1087#endif
1088
1ce7981b
HV
1089 dev->decoder = PHILIPS2;
1090 dev->io = io_port;
1091 dev->data = io_port + 1;
d56410e0 1092
1ce7981b
HV
1093 if (init_mediavision(dev)) {
1094 v4l2_err(v4l2_dev, "Board not found.\n");
1da177e4
LT
1095 return -ENODEV;
1096 }
1da177e4 1097
1ce7981b
HV
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 }
1da177e4 1103
1ce7981b
HV
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;
feba2f81 1107 dev->vdev.ioctl_ops = &pms_ioctl_ops;
1ce7981b
HV
1108 dev->vdev.release = video_device_release_empty;
1109 video_set_drvdata(&dev->vdev, dev);
1110 mutex_init(&dev->lock);
feba2f81 1111 dev->std = V4L2_STD_NTSC_M;
1ce7981b
HV
1112 dev->height = 240;
1113 dev->width = 320;
feba2f81
HV
1114 dev->depth = 15;
1115 dev->brightness = 139;
1116 dev->contrast = 70;
1117 dev->hue = 0;
1118 dev->saturation = 64;
1ce7981b
HV
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;
1da177e4
LT
1131}
1132
1ce7981b 1133static void __exit pms_exit(void)
1da177e4 1134{
1ce7981b 1135 struct pms *dev = &pms_card;
1da177e4 1136
1ce7981b
HV
1137 video_unregister_device(&dev->vdev);
1138 release_region(dev->io, 3);
1139 release_region(0x9a01, 1);
1140 iounmap(dev->mem);
1141}
1da177e4 1142
1ce7981b
HV
1143module_init(pms_init);
1144module_exit(pms_exit);