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