Linux Audio

Check our new training course

Loading...
   1/*
   2 *	Media Vision Pro Movie Studio
   3 *			or
   4 *	"all you need is an I2C bus some RAM and a prayer"
   5 *
   6 *	This draws heavily on code
   7 *
   8 *	(c) Wolfgang Koehler,  wolf@first.gmd.de, Dec. 1994
   9 *	Kiefernring 15
  10 *	14478 Potsdam, Germany
  11 *
  12 *	Most of this code is directly derived from his userspace driver.
  13 *	His driver works so send any reports to alan@lxorguk.ukuu.org.uk
  14 *	unless the userspace driver also doesn't work for you...
  15 *
  16 *      Changes:
  17 *	25-11-2009 	Hans Verkuil <hverkuil@xs4all.nl>
  18 * 			- converted to version 2 of the V4L API.
  19 *      08/07/2003      Daniele Bellucci <bellucda@tiscali.it>
  20 *                      - pms_capture: report back -EFAULT
  21 */
  22
  23#include <linux/module.h>
  24#include <linux/delay.h>
  25#include <linux/errno.h>
  26#include <linux/fs.h>
  27#include <linux/kernel.h>
  28#include <linux/mm.h>
  29#include <linux/slab.h>
  30#include <linux/ioport.h>
  31#include <linux/init.h>
  32#include <linux/mutex.h>
  33#include <linux/slab.h>
  34#include <linux/uaccess.h>
  35#include <linux/isa.h>
  36#include <asm/io.h>
  37
  38#include <linux/videodev2.h>
  39#include <media/v4l2-common.h>
  40#include <media/v4l2-ioctl.h>
  41#include <media/v4l2-ctrls.h>
  42#include <media/v4l2-fh.h>
  43#include <media/v4l2-event.h>
  44#include <media/v4l2-device.h>
  45
  46MODULE_LICENSE("GPL");
  47MODULE_VERSION("0.0.5");
  48
  49#define MOTOROLA	1
  50#define PHILIPS2	2               /* SAA7191 */
  51#define PHILIPS1	3
  52#define MVVMEMORYWIDTH	0x40		/* 512 bytes */
  53
  54struct i2c_info {
  55	u8 slave;
  56	u8 sub;
  57	u8 data;
  58	u8 hits;
  59};
  60
  61struct pms {
  62	struct v4l2_device v4l2_dev;
  63	struct video_device vdev;
  64	struct v4l2_ctrl_handler hdl;
  65	int height;
  66	int width;
  67	int depth;
  68	int input;
  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 */
  75	v4l2_std_id std;
  76	int io;
  77	int data;
  78	void __iomem *mem;
  79};
  80
  81/*
  82 *	I/O ports and Shared Memory
  83 */
  84
  85static int io_port = 0x250;
  86module_param(io_port, int, 0);
  87
  88static int mem_base = 0xc8000;
  89module_param(mem_base, int, 0);
  90
  91static int video_nr = -1;
  92module_param(video_nr, int, 0);
  93
  94
  95static inline void mvv_write(struct pms *dev, u8 index, u8 value)
  96{
  97	outw(index | (value << 8), dev->io);
  98}
  99
 100static inline u8 mvv_read(struct pms *dev, u8 index)
 101{
 102	outb(index, dev->io);
 103	return inb(dev->data);
 104}
 105
 106static int pms_i2c_stat(struct pms *dev, u8 slave)
 107{
 108	int counter = 0;
 109	int i;
 110
 111	outb(0x28, dev->io);
 112
 113	while ((inb(dev->data) & 0x01) == 0)
 114		if (counter++ == 256)
 115			break;
 116
 117	while ((inb(dev->data) & 0x01) != 0)
 118		if (counter++ == 256)
 119			break;
 120
 121	outb(slave, dev->io);
 122
 123	counter = 0;
 124	while ((inb(dev->data) & 0x01) == 0)
 125		if (counter++ == 256)
 126			break;
 127
 128	while ((inb(dev->data) & 0x01) != 0)
 129		if (counter++ == 256)
 130			break;
 131
 132	for (i = 0; i < 12; i++) {
 133		char st = inb(dev->data);
 134
 135		if ((st & 2) != 0)
 136			return -1;
 137		if ((st & 1) == 0)
 138			break;
 139	}
 140	outb(0x29, dev->io);
 141	return inb(dev->data);
 142}
 143
 144static int pms_i2c_write(struct pms *dev, u16 slave, u16 sub, u16 data)
 145{
 146	int skip = 0;
 147	int count;
 148	int i;
 149
 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;
 157		}
 158	}
 159
 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++;
 165	}
 166
 167	if (skip)
 168		return 0;
 169
 170	mvv_write(dev, 0x29, sub);
 171	mvv_write(dev, 0x2A, data);
 172	mvv_write(dev, 0x28, slave);
 173
 174	outb(0x28, dev->io);
 175
 176	count = 0;
 177	while ((inb(dev->data) & 1) == 0)
 178		if (count > 255)
 179			break;
 180	while ((inb(dev->data) & 1) != 0)
 181		if (count > 255)
 182			break;
 183
 184	count = inb(dev->data);
 185
 186	if (count & 2)
 187		return -1;
 188	return count;
 189}
 190
 191static int pms_i2c_read(struct pms *dev, int slave, int sub)
 192{
 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;
 198	}
 199	return 0;
 200}
 201
 202
 203static void pms_i2c_andor(struct pms *dev, int slave, int sub, int and, int or)
 204{
 205	u8 tmp;
 206
 207	tmp = pms_i2c_read(dev, slave, sub);
 208	tmp = (tmp & and) | or;
 209	pms_i2c_write(dev, slave, sub, tmp);
 210}
 211
 212/*
 213 *	Control functions
 214 */
 215
 216
 217static void pms_videosource(struct pms *dev, short source)
 218{
 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. */
 232}
 233
 234static void pms_hue(struct pms *dev, short hue)
 235{
 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;
 246	}
 247}
 248
 249static void pms_saturation(struct pms *dev, short sat)
 250{
 251	switch (dev->decoder) {
 252	case MOTOROLA:
 253		pms_i2c_write(dev, 0x8a, 0x00, sat);
 254		break;
 255	case PHILIPS1:
 256		pms_i2c_write(dev, 0x42, 0x12, sat);
 257		break;
 258	}
 259}
 260
 261
 262static void pms_contrast(struct pms *dev, short contrast)
 263{
 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;
 271	}
 272}
 273
 274static void pms_brightness(struct pms *dev, short brightness)
 275{
 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;
 285	}
 286}
 287
 288
 289static void pms_format(struct pms *dev, short format)
 290{
 291	int target;
 292
 293	dev->standard = format;
 294
 295	if (dev->decoder == PHILIPS1)
 296		target = 0x42;
 297	else if (dev->decoder == PHILIPS2)
 298		target = 0x8a;
 299	else
 300		return;
 301
 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;
 319	}
 320}
 321
 322#ifdef FOR_FUTURE_EXPANSION
 323
 324/*
 325 *	These features of the PMS card are not currently exposes. They
 326 *	could become a private v4l ioctl for PMSCONFIG or somesuch if
 327 *	people need it. We also don't yet use the PMS interrupt.
 328 */
 329
 330static void pms_hstart(struct pms *dev, short start)
 331{
 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;
 341	}
 342}
 343
 344/*
 345 *	Bandpass filters
 346 */
 347
 348static void pms_bandpass(struct pms *dev, short pass)
 349{
 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);
 354}
 355
 356static void pms_antisnow(struct pms *dev, short snow)
 357{
 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);
 362}
 363
 364static void pms_sharpness(struct pms *dev, short sharp)
 365{
 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);
 370}
 371
 372static void pms_chromaagc(struct pms *dev, short agc)
 373{
 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);
 378}
 379
 380static void pms_vertnoise(struct pms *dev, short noise)
 381{
 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);
 386}
 387
 388static void pms_forcecolour(struct pms *dev, short colour)
 389{
 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);
 394}
 395
 396static void pms_antigamma(struct pms *dev, short gamma)
 397{
 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);
 402}
 403
 404static void pms_prefilter(struct pms *dev, short filter)
 405{
 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);
 410}
 411
 412static void pms_hfilter(struct pms *dev, short filter)
 413{
 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);
 418}
 419
 420static void pms_vfilter(struct pms *dev, short filter)
 421{
 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);
 426}
 427
 428static void pms_killcolour(struct pms *dev, short colour)
 429{
 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);
 436	}
 437}
 438
 439static void pms_chromagain(struct pms *dev, short chroma)
 440{
 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);
 445}
 446
 447
 448static void pms_spacialcompl(struct pms *dev, short data)
 449{
 450	mvv_write(dev, 0x3b, data);
 451}
 452
 453static void pms_spacialcomph(struct pms *dev, short data)
 454{
 455	mvv_write(dev, 0x3a, data);
 456}
 457
 458static void pms_vstart(struct pms *dev, short start)
 459{
 460	mvv_write(dev, 0x16, start);
 461	mvv_write(dev, 0x17, (start >> 8) & 0x01);
 462}
 463
 464#endif
 465
 466static void pms_secamcross(struct pms *dev, short cross)
 467{
 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);
 472}
 473
 474
 475static void pms_swsense(struct pms *dev, short sense)
 476{
 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);
 483	}
 484}
 485
 486
 487static void pms_framerate(struct pms *dev, short frr)
 488{
 489	int fps = (dev->std & V4L2_STD_525_60) ? 30 : 25;
 490
 491	if (frr == 0)
 492		return;
 493	fps = fps/frr;
 494	mvv_write(dev, 0x14, 0x80 | fps);
 495	mvv_write(dev, 0x15, 1);
 496}
 497
 498static void pms_vert(struct pms *dev, u8 deciden, u8 decinum)
 499{
 500	mvv_write(dev, 0x1c, deciden);	/* Denominator */
 501	mvv_write(dev, 0x1d, decinum);	/* Numerator */
 502}
 503
 504/*
 505 *	Turn 16bit ratios into best small ratio the chipset can grok
 506 */
 507
 508static void pms_vertdeci(struct pms *dev, unsigned short decinum, unsigned short deciden)
 509{
 510	/* Knock it down by / 5 once */
 511	if (decinum % 5 == 0) {
 512		deciden /= 5;
 513		decinum /= 5;
 514	}
 515	/*
 516	 *	3's
 517	 */
 518	while (decinum % 3 == 0 && deciden % 3 == 0) {
 519		deciden /= 3;
 520		decinum /= 3;
 521	}
 522	/*
 523	 *	2's
 524	 */
 525	while (decinum % 2 == 0 && deciden % 2 == 0) {
 526		decinum /= 2;
 527		deciden /= 2;
 528	}
 529	/*
 530	 *	Fudgyify
 531	 */
 532	while (deciden > 32) {
 533		deciden /= 2;
 534		decinum = (decinum + 1) / 2;
 535	}
 536	if (deciden == 32)
 537		deciden--;
 538	pms_vert(dev, deciden, decinum);
 539}
 540
 541static void pms_horzdeci(struct pms *dev, short decinum, short deciden)
 542{
 543	if (decinum <= 512) {
 544		if (decinum % 5 == 0) {
 545			decinum /= 5;
 546			deciden /= 5;
 547		}
 548	} else {
 549		decinum = 512;
 550		deciden = 640;	/* 768 would be ideal */
 551	}
 552
 553	while (((decinum | deciden) & 1) == 0) {
 554		decinum >>= 1;
 555		deciden >>= 1;
 556	}
 557	while (deciden > 32) {
 558		deciden >>= 1;
 559		decinum = (decinum + 1) >> 1;
 560	}
 561	if (deciden == 32)
 562		deciden--;
 563
 564	mvv_write(dev, 0x24, 0x80 | deciden);
 565	mvv_write(dev, 0x25, decinum);
 566}
 567
 568static void pms_resolution(struct pms *dev, short width, short height)
 569{
 570	int fg_height;
 571
 572	fg_height = height;
 573	if (fg_height > 280)
 574		fg_height = 280;
 575
 576	mvv_write(dev, 0x18, fg_height);
 577	mvv_write(dev, 0x19, fg_height >> 8);
 578
 579	if (dev->std & V4L2_STD_525_60) {
 580		mvv_write(dev, 0x1a, 0xfc);
 581		mvv_write(dev, 0x1b, 0x00);
 582		if (height > fg_height)
 583			pms_vertdeci(dev, 240, 240);
 584		else
 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);
 591		else
 592			pms_vertdeci(dev, fg_height, 270);
 593	}
 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);
 599
 600	mvv_write(dev, 0x22, width + 8);
 601	mvv_write(dev, 0x23, (width + 8) >> 8);
 602
 603	if (dev->std & V4L2_STD_525_60)
 604		pms_horzdeci(dev, width, 640);
 605	else
 606		pms_horzdeci(dev, width + 8, 768);
 607
 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);
 613}
 614
 615
 616/*
 617 *	Set Input
 618 */
 619
 620static void pms_vcrinput(struct pms *dev, short input)
 621{
 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);
 626}
 627
 628
 629static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
 630{
 631	int y;
 632	int dw = 2 * dev->width;
 633	char tmp[dw + 32]; /* using a temp buffer is faster than direct  */
 634	int cnt = 0;
 635	int len = 0;
 636	unsigned char r8 = 0x5;  /* value for reg8  */
 637
 638	if (rgb555)
 639		r8 |= 0x20; /* else use untranslated rgb = 565 */
 640	mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
 641
 642/*	printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
 643
 644	for (y = 0; y < dev->height; y++) {
 645		writeb(0, dev->mem);  /* synchronisiert neue Zeile */
 646
 647		/*
 648		 *	This is in truth a fifo, be very careful as if you
 649		 *	forgot this odd things will occur 8)
 650		 */
 651
 652		memcpy_fromio(tmp, dev->mem, dw + 32); /* discard 16 word   */
 653		cnt -= dev->height;
 654		while (cnt <= 0) {
 655			/*
 656			 *	Don't copy too far
 657			 */
 658			int dt = dw;
 659			if (dt + len > count)
 660				dt = count - len;
 661			cnt += dev->height;
 662			if (copy_to_user(buf, tmp + 32, dt))
 663				return len ? len : -EFAULT;
 664			buf += dt;
 665			len += dt;
 666		}
 667	}
 668	return len;
 669}
 670
 671
 672/*
 673 *	Video4linux interfacing
 674 */
 675
 676static int pms_querycap(struct file *file, void  *priv,
 677					struct v4l2_capability *vcap)
 678{
 679	struct pms *dev = video_drvdata(file);
 680
 681	strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver));
 682	strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card));
 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;
 687	return 0;
 688}
 689
 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	};
 698
 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}
 709
 710static int pms_g_input(struct file *file, void *fh, unsigned int *inp)
 711{
 712	struct pms *dev = video_drvdata(file);
 713
 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
 725	dev->input = inp;
 726	pms_videosource(dev, inp & 1);
 727	pms_vcrinput(dev, inp >> 1);
 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;
 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;
 759	}
 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	}*/
 768	return ret;
 769}
 770
 771static int pms_s_ctrl(struct v4l2_ctrl *ctrl)
 772{
 773	struct pms *dev = container_of(ctrl->handler, struct pms, hdl);
 774	int ret = 0;
 775
 776	switch (ctrl->id) {
 777	case V4L2_CID_BRIGHTNESS:
 778		pms_brightness(dev, ctrl->val);
 779		break;
 780	case V4L2_CID_CONTRAST:
 781		pms_contrast(dev, ctrl->val);
 782		break;
 783	case V4L2_CID_SATURATION:
 784		pms_saturation(dev, ctrl->val);
 785		break;
 786	case V4L2_CID_HUE:
 787		pms_hue(dev, ctrl->val);
 788		break;
 789	default:
 790		ret = -EINVAL;
 791		break;
 792	}
 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;
 829	return 0;
 830}
 831
 832static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
 833{
 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;
 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 */
 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		},
 855		{ 1, 0, 0,
 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;
 868}
 869
 870static ssize_t pms_read(struct file *file, char __user *buf,
 871		    size_t count, loff_t *ppos)
 872{
 873	struct pms *dev = video_drvdata(file);
 874	int len;
 875
 876	len = pms_capture(dev, buf, (dev->depth == 15), count);
 877	return len;
 878}
 879
 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
 891static const struct v4l2_file_operations pms_fops = {
 892	.owner		= THIS_MODULE,
 893	.open           = v4l2_fh_open,
 894	.release        = v4l2_fh_release,
 895	.poll           = pms_poll,
 896	.unlocked_ioctl	= video_ioctl2,
 897	.read           = pms_read,
 898};
 899
 900static const struct v4l2_ioctl_ops pms_ioctl_ops = {
 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,
 913};
 914
 915/*
 916 *	Probe for and initialise the Mediavision PMS
 917 */
 918
 919static int init_mediavision(struct pms *dev)
 920{
 921	int idec, decst;
 922	int i;
 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
 931	};
 932
 933	dev->mem = ioremap(mem_base, 0x800);
 934	if (!dev->mem)
 935		return -ENOMEM;
 936
 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);
 940		return -EBUSY;
 941	}
 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);
 946		return -EBUSY;
 947	}
 948	outb(0xb8, 0x9a01);		/* Unlock */
 949	outb(dev->io >> 4, 0x9a01);	/* Set IO port */
 950
 951
 952	decst = pms_i2c_stat(dev, 0x43);
 953
 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;
 960	else
 961		idec = 0;
 962
 963	printk(KERN_INFO "PMS type is %d\n", idec);
 964	if (idec == 0) {
 965		release_region(dev->io, 3);
 966		release_region(0x9a01, 1);
 967		iounmap(dev->mem);
 968		return -ENODEV;
 969	}
 970
 971	/*
 972	 *	Ok we have a PMS of some sort
 973	 */
 974
 975	mvv_write(dev, 0x04, mem_base >> 12);	/* Set the memory area */
 976
 977	/* Ok now load the defaults */
 978
 979	for (i = 0; i < 0x19; i++) {
 980		if (i2c_defs[i] == 0xff)
 981			pms_i2c_andor(dev, 0x8a, i, 0x07, 0x00);
 982		else
 983			pms_i2c_write(dev, 0x8a, i, i2c_defs[i]);
 984	}
 985
 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);
1019	return 0;
1020}
1021
1022/*
1023 *	Initialization and module stuff
1024 */
1025
1026#ifndef MODULE
1027static int enable;
1028module_param(enable, int, 0);
1029#endif
1030
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)
1036{
1037	struct pms *dev;
1038	struct v4l2_device *v4l2_dev;
1039	struct v4l2_ctrl_handler *hdl;
1040	int res;
1041
1042#ifndef MODULE
1043	if (!enable) {
1044		pr_err("PMS: not enabled, use pms.enable=1 to probe\n");
1045		return -ENODEV;
1046	}
1047#endif
1048
1049	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1050	if (dev == NULL)
1051		return -ENOMEM;
1052
1053	dev->decoder = PHILIPS2;
1054	dev->io = io_port;
1055	dev->data = io_port + 1;
1056	v4l2_dev = &dev->v4l2_dev;
1057	hdl = &dev->hdl;
1058
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) {
1068		v4l2_err(v4l2_dev, "Board not found.\n");
1069		goto free_io;
1070	}
1071
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;
1084	}
1085
1086	mutex_init(&dev->lock);
1087	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
1088	dev->vdev.v4l2_dev = v4l2_dev;
1089	dev->vdev.ctrl_handler = hdl;
1090	dev->vdev.fops = &pms_fops;
1091	dev->vdev.ioctl_ops = &pms_ioctl_ops;
1092	dev->vdev.release = video_device_release_empty;
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);
1096	video_set_drvdata(&dev->vdev, dev);
1097	dev->std = V4L2_STD_NTSC_M;
1098	dev->height = 240;
1099	dev->width = 320;
1100	dev->depth = 16;
1101	pms_swsense(dev, 75);
1102	pms_resolution(dev, 320, 240);
1103	pms_videosource(dev, 0);
1104	pms_vcrinput(dev, 0);
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;
1120}
1121
1122static int pms_remove(struct device *pdev, unsigned int card)
1123{
1124	struct pms *dev = dev_get_drvdata(pdev);
1125
1126	video_unregister_device(&dev->vdev);
1127	v4l2_ctrl_handler_free(&dev->hdl);
1128	release_region(dev->io, 3);
1129	release_region(0x9a01, 1);
1130	iounmap(dev->mem);
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);
1150}
1151
1152module_init(pms_init);
1153module_exit(pms_exit);