linux/drivers/media/video/cpia_pp.c
<<
>>
Prefs
   1/*
   2 * cpia_pp CPiA Parallel Port driver
   3 *
   4 * Supports CPiA based parallel port Video Camera's.
   5 *
   6 * (C) Copyright 1999 Bas Huisman <bhuism@cs.utwente.nl>
   7 * (C) Copyright 1999-2000 Scott J. Bertin <sbertin@securenym.net>,
   8 * (C) Copyright 1999-2000 Peter Pregler <Peter_Pregler@email.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or
  13 * (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23 */
  24
  25/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
  26/* #define _CPIA_DEBUG_  1 */
  27
  28
  29#include <linux/module.h>
  30#include <linux/init.h>
  31
  32#include <linux/kernel.h>
  33#include <linux/parport.h>
  34#include <linux/interrupt.h>
  35#include <linux/delay.h>
  36#include <linux/workqueue.h>
  37#include <linux/sched.h>
  38
  39#include <linux/kmod.h>
  40
  41/* #define _CPIA_DEBUG_         define for verbose debug output */
  42#include "cpia.h"
  43
  44static int cpia_pp_open(void *privdata);
  45static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
  46                                    void *cbdata);
  47static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
  48static int cpia_pp_streamStart(void *privdata);
  49static int cpia_pp_streamStop(void *privdata);
  50static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);
  51static int cpia_pp_close(void *privdata);
  52
  53
  54#define ABOUT "Parallel port driver for Vision CPiA based cameras"
  55
  56#define PACKET_LENGTH  8
  57
  58/* Magic numbers for defining port-device mappings */
  59#define PPCPIA_PARPORT_UNSPEC -4
  60#define PPCPIA_PARPORT_AUTO -3
  61#define PPCPIA_PARPORT_OFF -2
  62#define PPCPIA_PARPORT_NONE -1
  63
  64static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
  65static char *parport[PARPORT_MAX] = {NULL,};
  66
  67MODULE_AUTHOR("B. Huisman <bhuism@cs.utwente.nl> & Peter Pregler <Peter_Pregler@email.com>");
  68MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");
  69MODULE_LICENSE("GPL");
  70
  71module_param_array(parport, charp, NULL, 0);
  72MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
  73
  74struct pp_cam_entry {
  75        struct pardevice *pdev;
  76        struct parport *port;
  77        struct work_struct cb_task;
  78        void (*cb_func)(void *cbdata);
  79        void *cb_data;
  80        int open_count;
  81        wait_queue_head_t wq_stream;
  82        /* image state flags */
  83        int image_ready;        /* we got an interrupt */
  84        int image_complete;     /* we have seen 4 EOI */
  85
  86        int streaming; /* we are in streaming mode */
  87        int stream_irq;
  88};
  89
  90static struct cpia_camera_ops cpia_pp_ops =
  91{
  92        cpia_pp_open,
  93        cpia_pp_registerCallback,
  94        cpia_pp_transferCmd,
  95        cpia_pp_streamStart,
  96        cpia_pp_streamStop,
  97        cpia_pp_streamRead,
  98        cpia_pp_close,
  99        1,
 100        THIS_MODULE
 101};
 102
 103static LIST_HEAD(cam_list);
 104static spinlock_t cam_list_lock_pp;
 105
 106/* FIXME */
 107static void cpia_parport_enable_irq( struct parport *port ) {
 108        parport_enable_irq(port);
 109        mdelay(10);
 110        return;
 111}
 112
 113static void cpia_parport_disable_irq( struct parport *port ) {
 114        parport_disable_irq(port);
 115        mdelay(10);
 116        return;
 117}
 118
 119/* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility
 120 * Link Flag during negotiation */
 121#define UPLOAD_FLAG  0x08
 122#define NIBBLE_TRANSFER 0x01
 123#define ECP_TRANSFER 0x03
 124
 125#define PARPORT_CHUNK_SIZE      PAGE_SIZE
 126
 127
 128static void cpia_pp_run_callback(struct work_struct *work)
 129{
 130        void (*cb_func)(void *cbdata);
 131        void *cb_data;
 132        struct pp_cam_entry *cam;
 133
 134        cam = container_of(work, struct pp_cam_entry, cb_task);
 135        cb_func = cam->cb_func;
 136        cb_data = cam->cb_data;
 137
 138        cb_func(cb_data);
 139}
 140
 141/****************************************************************************
 142 *
 143 *  CPiA-specific  low-level parport functions for nibble uploads
 144 *
 145 ***************************************************************************/
 146/*  CPiA nonstandard "Nibble" mode (no nDataAvail signal after each byte). */
 147/* The standard kernel parport_ieee1284_read_nibble() fails with the CPiA... */
 148
 149static size_t cpia_read_nibble (struct parport *port,
 150                         void *buffer, size_t len,
 151                         int flags)
 152{
 153        /* adapted verbatim, with one change, from
 154           parport_ieee1284_read_nibble() in drivers/parport/ieee1284-ops.c */
 155
 156        unsigned char *buf = buffer;
 157        int i;
 158        unsigned char byte = 0;
 159
 160        len *= 2; /* in nibbles */
 161        for (i=0; i < len; i++) {
 162                unsigned char nibble;
 163
 164                /* The CPiA firmware suppresses the use of nDataAvail (nFault LO)
 165                 * after every second nibble to signal that more
 166                 * data is available.  (the total number of Bytes that
 167                 * should be sent is known; if too few are received, an error
 168                 * will be recorded after a timeout).
 169                 * This is incompatible with parport_ieee1284_read_nibble(),
 170                 * which expects to find nFault LO after every second nibble.
 171                 */
 172
 173                /* Solution: modify cpia_read_nibble to only check for
 174                 * nDataAvail before the first nibble is sent.
 175                 */
 176
 177                /* Does the error line indicate end of data? */
 178                if (((i /*& 1*/) == 0) &&
 179                    (parport_read_status(port) & PARPORT_STATUS_ERROR)) {
 180                        DBG("%s: No more nibble data (%d bytes)\n",
 181                            port->name, i/2);
 182                        goto end_of_data;
 183                }
 184
 185                /* Event 7: Set nAutoFd low. */
 186                parport_frob_control (port,
 187                                      PARPORT_CONTROL_AUTOFD,
 188                                      PARPORT_CONTROL_AUTOFD);
 189
 190                /* Event 9: nAck goes low. */
 191                port->ieee1284.phase = IEEE1284_PH_REV_DATA;
 192                if (parport_wait_peripheral (port,
 193                                             PARPORT_STATUS_ACK, 0)) {
 194                        /* Timeout -- no more data? */
 195                                 DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
 196                                 port->name, i/2);
 197                        parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
 198                        break;
 199                }
 200
 201
 202                /* Read a nibble. */
 203                nibble = parport_read_status (port) >> 3;
 204                nibble &= ~8;
 205                if ((nibble & 0x10) == 0)
 206                        nibble |= 8;
 207                nibble &= 0xf;
 208
 209                /* Event 10: Set nAutoFd high. */
 210                parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
 211
 212                /* Event 11: nAck goes high. */
 213                if (parport_wait_peripheral (port,
 214                                             PARPORT_STATUS_ACK,
 215                                             PARPORT_STATUS_ACK)) {
 216                        /* Timeout -- no more data? */
 217                        DBG("%s: Nibble timeout at event 11\n",
 218                                 port->name);
 219                        break;
 220                }
 221
 222                if (i & 1) {
 223                        /* Second nibble */
 224                        byte |= nibble << 4;
 225                        *buf++ = byte;
 226                } else
 227                        byte = nibble;
 228        }
 229
 230        if (i == len) {
 231                /* Read the last nibble without checking data avail. */
 232                if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
 233                end_of_data:
 234                        /* Go to reverse idle phase. */
 235                        parport_frob_control (port,
 236                                              PARPORT_CONTROL_AUTOFD,
 237                                              PARPORT_CONTROL_AUTOFD);
 238                        port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
 239                }
 240                else
 241                        port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
 242        }
 243
 244        return i/2;
 245}
 246
 247/* CPiA nonstandard "Nibble Stream" mode (2 nibbles per cycle, instead of 1)
 248 * (See CPiA Data sheet p. 31)
 249 *
 250 * "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a
 251 * nonstandard variant of nibble mode which allows the same (mediocre)
 252 * data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable
 253 * parallel ports, but works also for  non-TRISTATE-capable ports.
 254 * (Standard nibble mode only send 4 bits per cycle)
 255 *
 256 */
 257
 258static size_t cpia_read_nibble_stream(struct parport *port,
 259                               void *buffer, size_t len,
 260                               int flags)
 261{
 262        int i;
 263        unsigned char *buf = buffer;
 264        int endseen = 0;
 265
 266        for (i=0; i < len; i++) {
 267                unsigned char nibble[2], byte = 0;
 268                int j;
 269
 270                /* Image Data is complete when 4 consecutive EOI bytes (0xff) are seen */
 271                if (endseen > 3 )
 272                        break;
 273
 274                /* Event 7: Set nAutoFd low. */
 275                parport_frob_control (port,
 276                                      PARPORT_CONTROL_AUTOFD,
 277                                      PARPORT_CONTROL_AUTOFD);
 278
 279                /* Event 9: nAck goes low. */
 280                port->ieee1284.phase = IEEE1284_PH_REV_DATA;
 281                if (parport_wait_peripheral (port,
 282                                             PARPORT_STATUS_ACK, 0)) {
 283                        /* Timeout -- no more data? */
 284                                 DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
 285                                 port->name, i/2);
 286                        parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
 287                        break;
 288                }
 289
 290                /* Read lower nibble */
 291                nibble[0] = parport_read_status (port) >>3;
 292
 293                /* Event 10: Set nAutoFd high. */
 294                parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
 295
 296                /* Event 11: nAck goes high. */
 297                if (parport_wait_peripheral (port,
 298                                             PARPORT_STATUS_ACK,
 299                                             PARPORT_STATUS_ACK)) {
 300                        /* Timeout -- no more data? */
 301                        DBG("%s: Nibble timeout at event 11\n",
 302                                 port->name);
 303                        break;
 304                }
 305
 306                /* Read upper nibble */
 307                nibble[1] = parport_read_status (port) >>3;
 308
 309                /* reassemble the byte */
 310                for (j = 0; j < 2 ; j++ ) {
 311                        nibble[j] &= ~8;
 312                        if ((nibble[j] & 0x10) == 0)
 313                                nibble[j] |= 8;
 314                        nibble[j] &= 0xf;
 315                }
 316                byte = (nibble[0] |(nibble[1] << 4));
 317                *buf++ = byte;
 318
 319                if(byte == EOI)
 320                  endseen++;
 321                else
 322                  endseen = 0;
 323        }
 324        return i;
 325}
 326
 327/****************************************************************************
 328 *
 329 *  EndTransferMode
 330 *
 331 ***************************************************************************/
 332static void EndTransferMode(struct pp_cam_entry *cam)
 333{
 334        parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
 335}
 336
 337/****************************************************************************
 338 *
 339 *  ForwardSetup
 340 *
 341 ***************************************************************************/
 342static int ForwardSetup(struct pp_cam_entry *cam)
 343{
 344        int retry;
 345
 346        /* The CPiA uses ECP protocol for Downloads from the Host to the camera.
 347         * This will be software-emulated if ECP hardware is not present
 348         */
 349
 350        /* the usual camera maximum response time is 10ms, but after receiving
 351         * some commands, it needs up to 40ms. (Data Sheet p. 32)*/
 352
 353        for(retry = 0; retry < 4; ++retry) {
 354                if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {
 355                        break;
 356                }
 357                mdelay(10);
 358        }
 359        if(retry == 4) {
 360                DBG("Unable to negotiate IEEE1284 ECP Download mode\n");
 361                return -1;
 362        }
 363        return 0;
 364}
 365/****************************************************************************
 366 *
 367 *  ReverseSetup
 368 *
 369 ***************************************************************************/
 370static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
 371{
 372        int retry;
 373        int upload_mode, mode = IEEE1284_MODE_ECP;
 374        int transfer_mode = ECP_TRANSFER;
 375
 376        if (!(cam->port->modes & PARPORT_MODE_ECP) &&
 377             !(cam->port->modes & PARPORT_MODE_TRISTATE)) {
 378                mode = IEEE1284_MODE_NIBBLE;
 379                transfer_mode = NIBBLE_TRANSFER;
 380        }
 381
 382        upload_mode = mode;
 383        if(extensibility) mode = UPLOAD_FLAG|transfer_mode|IEEE1284_EXT_LINK;
 384
 385        /* the usual camera maximum response time is 10ms, but after
 386         * receiving some commands, it needs up to 40ms. */
 387
 388        for(retry = 0; retry < 4; ++retry) {
 389                if(!parport_negotiate(cam->port, mode)) {
 390                        break;
 391                }
 392                mdelay(10);
 393        }
 394        if(retry == 4) {
 395                if(extensibility)
 396                        DBG("Unable to negotiate upload extensibility mode\n");
 397                else
 398                        DBG("Unable to negotiate upload mode\n");
 399                return -1;
 400        }
 401        if(extensibility) cam->port->ieee1284.mode = upload_mode;
 402        return 0;
 403}
 404
 405/****************************************************************************
 406 *
 407 *  WritePacket
 408 *
 409 ***************************************************************************/
 410static int WritePacket(struct pp_cam_entry *cam, const u8 *packet, size_t size)
 411{
 412        int retval=0;
 413        int size_written;
 414
 415        if (packet == NULL) {
 416                return -EINVAL;
 417        }
 418        if (ForwardSetup(cam)) {
 419                DBG("Write failed in setup\n");
 420                return -EIO;
 421        }
 422        size_written = parport_write(cam->port, packet, size);
 423        if(size_written != size) {
 424                DBG("Write failed, wrote %d/%d\n", size_written, size);
 425                retval = -EIO;
 426        }
 427        EndTransferMode(cam);
 428        return retval;
 429}
 430
 431/****************************************************************************
 432 *
 433 *  ReadPacket
 434 *
 435 ***************************************************************************/
 436static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
 437{
 438        int retval=0;
 439
 440        if (packet == NULL) {
 441                return -EINVAL;
 442        }
 443        if (ReverseSetup(cam, 0)) {
 444                return -EIO;
 445        }
 446
 447        /* support for CPiA variant nibble reads */
 448        if(cam->port->ieee1284.mode == IEEE1284_MODE_NIBBLE) {
 449                if(cpia_read_nibble(cam->port, packet, size, 0) != size)
 450                        retval = -EIO;
 451        } else {
 452                if(parport_read(cam->port, packet, size) != size)
 453                        retval = -EIO;
 454        }
 455        EndTransferMode(cam);
 456        return retval;
 457}
 458
 459/****************************************************************************
 460 *
 461 *  cpia_pp_streamStart
 462 *
 463 ***************************************************************************/
 464static int cpia_pp_streamStart(void *privdata)
 465{
 466        struct pp_cam_entry *cam = privdata;
 467        DBG("\n");
 468        cam->streaming=1;
 469        cam->image_ready=0;
 470        //if (ReverseSetup(cam,1)) return -EIO;
 471        if(cam->stream_irq) cpia_parport_enable_irq(cam->port);
 472        return 0;
 473}
 474
 475/****************************************************************************
 476 *
 477 *  cpia_pp_streamStop
 478 *
 479 ***************************************************************************/
 480static int cpia_pp_streamStop(void *privdata)
 481{
 482        struct pp_cam_entry *cam = privdata;
 483
 484        DBG("\n");
 485        cam->streaming=0;
 486        cpia_parport_disable_irq(cam->port);
 487        //EndTransferMode(cam);
 488
 489        return 0;
 490}
 491
 492/****************************************************************************
 493 *
 494 *  cpia_pp_streamRead
 495 *
 496 ***************************************************************************/
 497static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
 498{
 499        int bytes_read;
 500
 501        /* support for CPiA variant "nibble stream" reads */
 502        if(port->ieee1284.mode == IEEE1284_MODE_NIBBLE)
 503                bytes_read = cpia_read_nibble_stream(port,buffer,len,0);
 504        else {
 505                int new_bytes;
 506                for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
 507                        new_bytes = parport_read(port, buffer+bytes_read,
 508                                                 len-bytes_read);
 509                        if(new_bytes < 0) break;
 510                }
 511        }
 512        return bytes_read;
 513}
 514
 515static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
 516{
 517        struct pp_cam_entry *cam = privdata;
 518        int read_bytes = 0;
 519        int i, endseen, block_size, new_bytes;
 520
 521        if(cam == NULL) {
 522                DBG("Internal driver error: cam is NULL\n");
 523                return -EINVAL;
 524        }
 525        if(buffer == NULL) {
 526                DBG("Internal driver error: buffer is NULL\n");
 527                return -EINVAL;
 528        }
 529        //if(cam->streaming) DBG("%d / %d\n", cam->image_ready, noblock);
 530        if( cam->stream_irq ) {
 531                DBG("%d\n", cam->image_ready);
 532                cam->image_ready--;
 533        }
 534        cam->image_complete=0;
 535        if (0/*cam->streaming*/) {
 536                if(!cam->image_ready) {
 537                        if(noblock) return -EWOULDBLOCK;
 538                        interruptible_sleep_on(&cam->wq_stream);
 539                        if( signal_pending(current) ) return -EINTR;
 540                        DBG("%d\n", cam->image_ready);
 541                }
 542        } else {
 543                if (ReverseSetup(cam, 1)) {
 544                        DBG("unable to ReverseSetup\n");
 545                        return -EIO;
 546                }
 547        }
 548        endseen = 0;
 549        block_size = PARPORT_CHUNK_SIZE;
 550        while( !cam->image_complete ) {
 551                cond_resched();
 552
 553                new_bytes = cpia_pp_read(cam->port, buffer, block_size );
 554                if( new_bytes <= 0 ) {
 555                        break;
 556                }
 557                i=-1;
 558                while(++i<new_bytes && endseen<4) {
 559                        if(*buffer==EOI) {
 560                                endseen++;
 561                        } else {
 562                                endseen=0;
 563                        }
 564                        buffer++;
 565                }
 566                read_bytes += i;
 567                if( endseen==4 ) {
 568                        cam->image_complete=1;
 569                        break;
 570                }
 571                if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
 572                        block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
 573                }
 574        }
 575        EndTransferMode(cam);
 576        return cam->image_complete ? read_bytes : -EIO;
 577}
 578/****************************************************************************
 579 *
 580 *  cpia_pp_transferCmd
 581 *
 582 ***************************************************************************/
 583static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
 584{
 585        int err;
 586        int retval=0;
 587        int databytes;
 588        struct pp_cam_entry *cam = privdata;
 589
 590        if(cam == NULL) {
 591                DBG("Internal driver error: cam is NULL\n");
 592                return -EINVAL;
 593        }
 594        if(command == NULL) {
 595                DBG("Internal driver error: command is NULL\n");
 596                return -EINVAL;
 597        }
 598        databytes = (((int)command[7])<<8) | command[6];
 599        if ((err = WritePacket(cam, command, PACKET_LENGTH)) < 0) {
 600                DBG("Error writing command\n");
 601                return err;
 602        }
 603        if(command[0] == DATA_IN) {
 604                u8 buffer[8];
 605                if(data == NULL) {
 606                        DBG("Internal driver error: data is NULL\n");
 607                        return -EINVAL;
 608                }
 609                if((err = ReadPacket(cam, buffer, 8)) < 0) {
 610                        DBG("Error reading command result\n");
 611                       return err;
 612                }
 613                memcpy(data, buffer, databytes);
 614        } else if(command[0] == DATA_OUT) {
 615                if(databytes > 0) {
 616                        if(data == NULL) {
 617                                DBG("Internal driver error: data is NULL\n");
 618                                retval = -EINVAL;
 619                        } else {
 620                                if((err=WritePacket(cam, data, databytes)) < 0){
 621                                        DBG("Error writing command data\n");
 622                                        return err;
 623                                }
 624                        }
 625                }
 626        } else {
 627                DBG("Unexpected first byte of command: %x\n", command[0]);
 628                retval = -EINVAL;
 629        }
 630        return retval;
 631}
 632
 633/****************************************************************************
 634 *
 635 *  cpia_pp_open
 636 *
 637 ***************************************************************************/
 638static int cpia_pp_open(void *privdata)
 639{
 640        struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
 641
 642        if (cam == NULL)
 643                return -EINVAL;
 644
 645        if(cam->open_count == 0) {
 646                if (parport_claim(cam->pdev)) {
 647                        DBG("failed to claim the port\n");
 648                        return -EBUSY;
 649                }
 650                parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
 651                parport_data_forward(cam->port);
 652                parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
 653                udelay(50);
 654                parport_write_control(cam->port,
 655                                      PARPORT_CONTROL_SELECT
 656                                      | PARPORT_CONTROL_INIT);
 657        }
 658
 659        ++cam->open_count;
 660
 661        return 0;
 662}
 663
 664/****************************************************************************
 665 *
 666 *  cpia_pp_registerCallback
 667 *
 668 ***************************************************************************/
 669static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), void *cbdata)
 670{
 671        struct pp_cam_entry *cam = privdata;
 672        int retval = 0;
 673
 674        if(cam->port->irq != PARPORT_IRQ_NONE) {
 675                cam->cb_func = cb;
 676                cam->cb_data = cbdata;
 677                INIT_WORK(&cam->cb_task, cpia_pp_run_callback);
 678        } else {
 679                retval = -1;
 680        }
 681        return retval;
 682}
 683
 684/****************************************************************************
 685 *
 686 *  cpia_pp_close
 687 *
 688 ***************************************************************************/
 689static int cpia_pp_close(void *privdata)
 690{
 691        struct pp_cam_entry *cam = privdata;
 692        if (--cam->open_count == 0) {
 693                parport_release(cam->pdev);
 694        }
 695        return 0;
 696}
 697
 698/****************************************************************************
 699 *
 700 *  cpia_pp_register
 701 *
 702 ***************************************************************************/
 703static int cpia_pp_register(struct parport *port)
 704{
 705        struct pardevice *pdev = NULL;
 706        struct pp_cam_entry *cam;
 707        struct cam_data *cpia;
 708
 709        if (!(port->modes & PARPORT_MODE_PCSPP)) {
 710                LOG("port is not supported by CPiA driver\n");
 711                return -ENXIO;
 712        }
 713
 714        cam = kzalloc(sizeof(struct pp_cam_entry), GFP_KERNEL);
 715        if (cam == NULL) {
 716                LOG("failed to allocate camera structure\n");
 717                return -ENOMEM;
 718        }
 719
 720        pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
 721                                       NULL, 0, cam);
 722
 723        if (!pdev) {
 724                LOG("failed to parport_register_device\n");
 725                kfree(cam);
 726                return -ENXIO;
 727        }
 728
 729        cam->pdev = pdev;
 730        cam->port = port;
 731        init_waitqueue_head(&cam->wq_stream);
 732
 733        cam->streaming = 0;
 734        cam->stream_irq = 0;
 735
 736        if((cpia = cpia_register_camera(&cpia_pp_ops, cam)) == NULL) {
 737                LOG("failed to cpia_register_camera\n");
 738                parport_unregister_device(pdev);
 739                kfree(cam);
 740                return -ENXIO;
 741        }
 742        spin_lock( &cam_list_lock_pp );
 743        list_add( &cpia->cam_data_list, &cam_list );
 744        spin_unlock( &cam_list_lock_pp );
 745
 746        return 0;
 747}
 748
 749static void cpia_pp_detach (struct parport *port)
 750{
 751        struct list_head *tmp;
 752        struct cam_data *cpia = NULL;
 753        struct pp_cam_entry *cam;
 754
 755        spin_lock( &cam_list_lock_pp );
 756        list_for_each (tmp, &cam_list) {
 757                cpia = list_entry(tmp, struct cam_data, cam_data_list);
 758                cam = (struct pp_cam_entry *) cpia->lowlevel_data;
 759                if (cam && cam->port->number == port->number) {
 760                        list_del(&cpia->cam_data_list);
 761                        break;
 762                }
 763                cpia = NULL;
 764        }
 765        spin_unlock( &cam_list_lock_pp );
 766
 767        if (!cpia) {
 768                DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
 769                return;
 770        }
 771
 772        cam = (struct pp_cam_entry *) cpia->lowlevel_data;
 773        cpia_unregister_camera(cpia);
 774        if(cam->open_count > 0)
 775                cpia_pp_close(cam);
 776        parport_unregister_device(cam->pdev);
 777        cpia->lowlevel_data = NULL;
 778        kfree(cam);
 779}
 780
 781static void cpia_pp_attach (struct parport *port)
 782{
 783        unsigned int i;
 784
 785        switch (parport_nr[0])
 786        {
 787        case PPCPIA_PARPORT_UNSPEC:
 788        case PPCPIA_PARPORT_AUTO:
 789                if (port->probe_info[0].class != PARPORT_CLASS_MEDIA ||
 790                    port->probe_info[0].cmdset == NULL ||
 791                    strncmp(port->probe_info[0].cmdset, "CPIA_1", 6) != 0)
 792                        return;
 793
 794                cpia_pp_register(port);
 795
 796                break;
 797
 798        default:
 799                for (i = 0; i < PARPORT_MAX; ++i) {
 800                        if (port->number == parport_nr[i]) {
 801                                cpia_pp_register(port);
 802                                break;
 803                        }
 804                }
 805                break;
 806        }
 807}
 808
 809static struct parport_driver cpia_pp_driver = {
 810        .name = "cpia_pp",
 811        .attach = cpia_pp_attach,
 812        .detach = cpia_pp_detach,
 813};
 814
 815static int __init cpia_pp_init(void)
 816{
 817        printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
 818               CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
 819
 820        if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
 821                printk("  disabled\n");
 822                return 0;
 823        }
 824
 825        spin_lock_init( &cam_list_lock_pp );
 826
 827        if (parport_register_driver (&cpia_pp_driver)) {
 828                LOG ("unable to register with parport\n");
 829                return -EIO;
 830        }
 831        return 0;
 832}
 833
 834static int __init cpia_init(void)
 835{
 836        if (parport[0]) {
 837                /* The user gave some parameters.  Let's see what they were. */
 838                if (!strncmp(parport[0], "auto", 4)) {
 839                        parport_nr[0] = PPCPIA_PARPORT_AUTO;
 840                } else {
 841                        int n;
 842                        for (n = 0; n < PARPORT_MAX && parport[n]; n++) {
 843                                if (!strncmp(parport[n], "none", 4)) {
 844                                        parport_nr[n] = PPCPIA_PARPORT_NONE;
 845                                } else {
 846                                        char *ep;
 847                                        unsigned long r = simple_strtoul(parport[n], &ep, 0);
 848                                        if (ep != parport[n]) {
 849                                                parport_nr[n] = r;
 850                                        } else {
 851                                                LOG("bad port specifier `%s'\n", parport[n]);
 852                                                return -ENODEV;
 853                                        }
 854                                }
 855                        }
 856                }
 857        }
 858        return cpia_pp_init();
 859}
 860
 861static void __exit cpia_cleanup(void)
 862{
 863        parport_unregister_driver(&cpia_pp_driver);
 864        return;
 865}
 866
 867module_init(cpia_init);
 868module_exit(cpia_cleanup);
 869