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