OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [media/] [video/] [cpia_pp.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
#include <linux/config.h>
29
#include <linux/version.h>
30
 
31
#include <linux/module.h>
32
#include <linux/init.h>
33
 
34
#include <linux/kernel.h>
35
#include <linux/parport.h>
36
#include <linux/interrupt.h>
37
#include <linux/delay.h>
38
#include <linux/smp_lock.h>
39
#include <linux/sched.h>
40
 
41
#include <linux/kmod.h>
42
 
43
/* #define _CPIA_DEBUG_         define for verbose debug output */
44
#include "cpia.h"
45
 
46
static int cpia_pp_open(void *privdata);
47
static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
48
                                    void *cbdata);
49
static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
50
static int cpia_pp_streamStart(void *privdata);
51
static int cpia_pp_streamStop(void *privdata);
52
static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);
53
static int cpia_pp_close(void *privdata);
54
 
55
#define ABOUT "Parallel port driver for Vision CPiA based cameras"
56
 
57
#define PACKET_LENGTH   8
58
 
59
/* Magic numbers for defining port-device mappings */
60
#define PPCPIA_PARPORT_UNSPEC -4
61
#define PPCPIA_PARPORT_AUTO -3
62
#define PPCPIA_PARPORT_OFF -2
63
#define PPCPIA_PARPORT_NONE -1
64
 
65
#ifdef MODULE
66
static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
67
static char *parport[PARPORT_MAX] = {NULL,};
68
 
69
MODULE_AUTHOR("B. Huisman <bhuism@cs.utwente.nl> & Peter Pregler <Peter_Pregler@email.com>");
70
MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");
71
MODULE_LICENSE("GPL");
72
 
73
MODULE_PARM(parport, "1-" __MODULE_STRING(PARPORT_MAX) "s");
74
MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
75
#else
76
static int parport_nr[PARPORT_MAX] __initdata =
77
        {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
78
static int parport_ptr = 0;
79
#endif
80
 
81
struct pp_cam_entry {
82
        struct pardevice *pdev;
83
        struct parport *port;
84
        struct tq_struct cb_task;
85
        int open_count;
86
        wait_queue_head_t wq_stream;
87
        /* image state flags */
88
        int image_ready;        /* we got an interrupt */
89
        int image_complete;     /* we have seen 4 EOI */
90
 
91
        int streaming; /* we are in streaming mode */
92
        int stream_irq;
93
};
94
 
95
static struct cpia_camera_ops cpia_pp_ops =
96
{
97
        cpia_pp_open,
98
        cpia_pp_registerCallback,
99
        cpia_pp_transferCmd,
100
        cpia_pp_streamStart,
101
        cpia_pp_streamStop,
102
        cpia_pp_streamRead,
103
        cpia_pp_close,
104
        1,
105
        THIS_MODULE
106
};
107
 
108
static LIST_HEAD(cam_list);
109
static spinlock_t cam_list_lock_pp;
110
 
111
/* FIXME */
112
static void cpia_parport_enable_irq( struct parport *port ) {
113
        parport_enable_irq(port);
114
        mdelay(10);
115
        return;
116
}
117
 
118
static void cpia_parport_disable_irq( struct parport *port ) {
119
        parport_disable_irq(port);
120
        mdelay(10);
121
        return;
122
}
123
 
124
/* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility
125
 * Link Flag during negotiation */
126
#define UPLOAD_FLAG  0x08
127
#define ECP_TRANSFER 0x03
128
 
129
#define PARPORT_CHUNK_SIZE      PAGE_SIZE
130
 
131
 
132
/****************************************************************************
133
 *
134
 *  EndTransferMode
135
 *
136
 ***************************************************************************/
137
static void EndTransferMode(struct pp_cam_entry *cam)
138
{
139
        parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
140
}
141
 
142
/****************************************************************************
143
 *
144
 *  ForwardSetup
145
 *
146
 ***************************************************************************/
147
static int ForwardSetup(struct pp_cam_entry *cam)
148
{
149
        int retry;
150
 
151
        /* After some commands the camera needs extra time before
152
         * it will respond again, so we try up to 3 times */
153
        for(retry=0; retry<3; ++retry) {
154
                if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {
155
                        break;
156
                }
157
        }
158
        if(retry == 3) {
159
                DBG("Unable to negotiate ECP mode\n");
160
                return -1;
161
        }
162
        return 0;
163
}
164
 
165
/****************************************************************************
166
 *
167
 *  ReverseSetup
168
 *
169
 ***************************************************************************/
170
static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
171
{
172
        int retry;
173
        int mode = IEEE1284_MODE_ECP;
174
        if(extensibility) mode = UPLOAD_FLAG|ECP_TRANSFER|IEEE1284_EXT_LINK;
175
 
176
        /* After some commands the camera needs extra time before
177
         * it will respond again, so we try up to 3 times */
178
        for(retry=0; retry<3; ++retry) {
179
                if(!parport_negotiate(cam->port, mode)) {
180
                        break;
181
                }
182
        }
183
        if(retry == 3) {
184
                if(extensibility)
185
                        DBG("Unable to negotiate extensibility mode\n");
186
                else
187
                        DBG("Unable to negotiate ECP mode\n");
188
                return -1;
189
        }
190
        if(extensibility) cam->port->ieee1284.mode = IEEE1284_MODE_ECP;
191
        return 0;
192
}
193
 
194
/****************************************************************************
195
 *
196
 *  WritePacket
197
 *
198
 ***************************************************************************/
199
static int WritePacket(struct pp_cam_entry *cam, const u8 *packet, size_t size)
200
{
201
        int retval=0;
202
        int size_written;
203
 
204
        if (packet == NULL) {
205
                return -EINVAL;
206
        }
207
        if (ForwardSetup(cam)) {
208
                DBG("Write failed in setup\n");
209
                return -EIO;
210
        }
211
        size_written = parport_write(cam->port, packet, size);
212
        if(size_written != size) {
213
                DBG("Write failed, wrote %d/%d\n", size_written, size);
214
                retval = -EIO;
215
        }
216
        EndTransferMode(cam);
217
        return retval;
218
}
219
 
220
/****************************************************************************
221
 *
222
 *  ReadPacket
223
 *
224
 ***************************************************************************/
225
static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
226
{
227
        int retval=0;
228
        if (packet == NULL) {
229
                return -EINVAL;
230
        }
231
        if (ReverseSetup(cam, 0)) {
232
                return -EIO;
233
        }
234
        if(parport_read(cam->port, packet, size) != size) {
235
                retval = -EIO;
236
        }
237
        EndTransferMode(cam);
238
        return retval;
239
}
240
 
241
/****************************************************************************
242
 *
243
 *  cpia_pp_streamStart
244
 *
245
 ***************************************************************************/
246
static int cpia_pp_streamStart(void *privdata)
247
{
248
        struct pp_cam_entry *cam = privdata;
249
        DBG("\n");
250
        cam->streaming=1;
251
        cam->image_ready=0;
252
        //if (ReverseSetup(cam,1)) return -EIO;
253
        if(cam->stream_irq) cpia_parport_enable_irq(cam->port);
254
        return 0;
255
}
256
 
257
/****************************************************************************
258
 *
259
 *  cpia_pp_streamStop
260
 *
261
 ***************************************************************************/
262
static int cpia_pp_streamStop(void *privdata)
263
{
264
        struct pp_cam_entry *cam = privdata;
265
 
266
        DBG("\n");
267
        cam->streaming=0;
268
        cpia_parport_disable_irq(cam->port);
269
        //EndTransferMode(cam);
270
 
271
        return 0;
272
}
273
 
274
/****************************************************************************
275
 *
276
 *  cpia_pp_streamRead
277
 *
278
 ***************************************************************************/
279
static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
280
{
281
        int bytes_read, new_bytes;
282
        for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
283
                new_bytes = parport_read(port, buffer+bytes_read,
284
                                         len-bytes_read);
285
                if(new_bytes < 0) break;
286
        }
287
        return bytes_read;
288
}
289
 
290
static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
291
{
292
        struct pp_cam_entry *cam = privdata;
293
        int read_bytes = 0;
294
        int i, endseen, block_size, new_bytes;
295
 
296
        if(cam == NULL) {
297
                DBG("Internal driver error: cam is NULL\n");
298
                return -EINVAL;
299
        }
300
        if(buffer == NULL) {
301
                DBG("Internal driver error: buffer is NULL\n");
302
                return -EINVAL;
303
        }
304
        //if(cam->streaming) DBG("%d / %d\n", cam->image_ready, noblock);
305
        if( cam->stream_irq ) {
306
                DBG("%d\n", cam->image_ready);
307
                cam->image_ready--;
308
        }
309
        cam->image_complete=0;
310
        if (0/*cam->streaming*/) {
311
                if(!cam->image_ready) {
312
                        if(noblock) return -EWOULDBLOCK;
313
                        interruptible_sleep_on(&cam->wq_stream);
314
                        if( signal_pending(current) ) return -EINTR;
315
                        DBG("%d\n", cam->image_ready);
316
                }
317
        } else {
318
                if (ReverseSetup(cam, 1)) {
319
                        DBG("unable to ReverseSetup\n");
320
                        return -EIO;
321
                }
322
        }
323
        endseen = 0;
324
        block_size = PARPORT_CHUNK_SIZE;
325
        while( !cam->image_complete ) {
326
                if(current->need_resched)  schedule();
327
 
328
                new_bytes = cpia_pp_read(cam->port, buffer, block_size );
329
                if( new_bytes <= 0 ) {
330
                        break;
331
                }
332
                i=-1;
333
                while(++i<new_bytes && endseen<4) {
334
                        if(*buffer==EOI) {
335
                                endseen++;
336
                        } else {
337
                                endseen=0;
338
                        }
339
                        buffer++;
340
                }
341
                read_bytes += i;
342
                if( endseen==4 ) {
343
                        cam->image_complete=1;
344
                        break;
345
                }
346
                if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
347
                        block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
348
                }
349
        }
350
        EndTransferMode(cam);
351
        return cam->image_complete ? read_bytes : -EIO;
352
}
353
 
354
/****************************************************************************
355
 *
356
 *  cpia_pp_transferCmd
357
 *
358
 ***************************************************************************/
359
static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
360
{
361
        int err;
362
        int retval=0;
363
        int databytes;
364
        struct pp_cam_entry *cam = privdata;
365
 
366
        if(cam == NULL) {
367
                DBG("Internal driver error: cam is NULL\n");
368
                return -EINVAL;
369
        }
370
        if(command == NULL) {
371
                DBG("Internal driver error: command is NULL\n");
372
                return -EINVAL;
373
        }
374
        databytes = (((int)command[7])<<8) | command[6];
375
        if ((err = WritePacket(cam, command, PACKET_LENGTH)) < 0) {
376
                DBG("Error writing command\n");
377
                return err;
378
        }
379
        if(command[0] == DATA_IN) {
380
                u8 buffer[8];
381
                if(data == NULL) {
382
                        DBG("Internal driver error: data is NULL\n");
383
                        return -EINVAL;
384
                }
385
                if((err = ReadPacket(cam, buffer, 8)) < 0) {
386
                        DBG("Error reading command result\n");
387
                       return err;
388
                }
389
                memcpy(data, buffer, databytes);
390
        } else if(command[0] == DATA_OUT) {
391
                if(databytes > 0) {
392
                        if(data == NULL) {
393
                                DBG("Internal driver error: data is NULL\n");
394
                                retval = -EINVAL;
395
                        } else {
396
                                if((err=WritePacket(cam, data, databytes)) < 0){
397
                                        DBG("Error writing command data\n");
398
                                        return err;
399
                                }
400
                        }
401
                }
402
        } else {
403
                DBG("Unexpected first byte of command: %x\n", command[0]);
404
                retval = -EINVAL;
405
        }
406
        return retval;
407
}
408
 
409
/****************************************************************************
410
 *
411
 *  cpia_pp_open
412
 *
413
 ***************************************************************************/
414
static int cpia_pp_open(void *privdata)
415
{
416
        struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
417
 
418
        if (cam == NULL)
419
                return -EINVAL;
420
 
421
        if(cam->open_count == 0) {
422
                if (parport_claim(cam->pdev)) {
423
                        DBG("failed to claim the port\n");
424
                        return -EBUSY;
425
                }
426
                parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
427
                parport_data_forward(cam->port);
428
                parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
429
                udelay(50);
430
                parport_write_control(cam->port,
431
                                      PARPORT_CONTROL_SELECT
432
                                      | PARPORT_CONTROL_INIT);
433
        }
434
 
435
        ++cam->open_count;
436
 
437
        return 0;
438
}
439
 
440
/****************************************************************************
441
 *
442
 *  cpia_pp_registerCallback
443
 *
444
 ***************************************************************************/
445
static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), void *cbdata)
446
{
447
        struct pp_cam_entry *cam = privdata;
448
        int retval = 0;
449
 
450
        if(cam->port->irq != PARPORT_IRQ_NONE) {
451
                cam->cb_task.routine = cb;
452
                cam->cb_task.data = cbdata;
453
        } else {
454
                retval = -1;
455
        }
456
        return retval;
457
}
458
 
459
/****************************************************************************
460
 *
461
 *  cpia_pp_close
462
 *
463
 ***************************************************************************/
464
static int cpia_pp_close(void *privdata)
465
{
466
        struct pp_cam_entry *cam = privdata;
467
        if (--cam->open_count == 0) {
468
                parport_release(cam->pdev);
469
        }
470
        return 0;
471
}
472
 
473
/****************************************************************************
474
 *
475
 *  cpia_pp_register
476
 *
477
 ***************************************************************************/
478
static int cpia_pp_register(struct parport *port)
479
{
480
        struct pardevice *pdev = NULL;
481
        struct pp_cam_entry *cam;
482
        struct cam_data *cpia;
483
 
484
        if (!(port->modes & PARPORT_MODE_ECP) &&
485
            !(port->modes & PARPORT_MODE_TRISTATE)) {
486
                LOG("port is not ECP capable\n");
487
                return -ENXIO;
488
        }
489
 
490
        cam = kmalloc(sizeof(struct pp_cam_entry), GFP_KERNEL);
491
        if (cam == NULL) {
492
                LOG("failed to allocate camera structure\n");
493
                return -ENOMEM;
494
        }
495
        memset(cam,0,sizeof(struct pp_cam_entry));
496
 
497
        pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
498
                                       NULL, 0, cam);
499
 
500
        if (!pdev) {
501
                LOG("failed to parport_register_device\n");
502
                kfree(cam);
503
                return -ENXIO;
504
        }
505
 
506
        cam->pdev = pdev;
507
        cam->port = port;
508
        init_waitqueue_head(&cam->wq_stream);
509
 
510
        cam->streaming = 0;
511
        cam->stream_irq = 0;
512
 
513
        if((cpia = cpia_register_camera(&cpia_pp_ops, cam)) == NULL) {
514
                LOG("failed to cpia_register_camera\n");
515
                parport_unregister_device(pdev);
516
                kfree(cam);
517
                return -ENXIO;
518
        }
519
        spin_lock( &cam_list_lock_pp );
520
        list_add( &cpia->cam_data_list, &cam_list );
521
        spin_unlock( &cam_list_lock_pp );
522
 
523
        return 0;
524
}
525
 
526
static void cpia_pp_detach (struct parport *port)
527
{
528
        struct list_head *tmp;
529
        struct cam_data *cpia = NULL;
530
        struct pp_cam_entry *cam;
531
 
532
        spin_lock( &cam_list_lock_pp );
533
        list_for_each (tmp, &cam_list) {
534
                cpia = list_entry(tmp, struct cam_data, cam_data_list);
535
                cam = (struct pp_cam_entry *) cpia->lowlevel_data;
536
                if (cam && cam->port->number == port->number) {
537
                        list_del(&cpia->cam_data_list);
538
                        break;
539
                }
540
                cpia = NULL;
541
        }
542
        spin_unlock( &cam_list_lock_pp );
543
 
544
        if (!cpia) {
545
                DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
546
                return;
547
        }
548
 
549
        cam = (struct pp_cam_entry *) cpia->lowlevel_data;
550
        cpia_unregister_camera(cpia);
551
        if(cam->open_count > 0)
552
                cpia_pp_close(cam);
553
        parport_unregister_device(cam->pdev);
554
        cpia->lowlevel_data = NULL;
555
        kfree(cam);
556
}
557
 
558
static void cpia_pp_attach (struct parport *port)
559
{
560
        unsigned int i;
561
 
562
        switch (parport_nr[0])
563
        {
564
        case PPCPIA_PARPORT_UNSPEC:
565
        case PPCPIA_PARPORT_AUTO:
566
                if (port->probe_info[0].class != PARPORT_CLASS_MEDIA ||
567
                    port->probe_info[0].cmdset == NULL ||
568
                    strncmp(port->probe_info[0].cmdset, "CPIA_1", 6) != 0)
569
                        return;
570
 
571
                cpia_pp_register(port);
572
 
573
                break;
574
 
575
        default:
576
                for (i = 0; i < PARPORT_MAX; ++i) {
577
                        if (port->number == parport_nr[i]) {
578
                                cpia_pp_register(port);
579
                                break;
580
                        }
581
                }
582
                break;
583
        }
584
}
585
 
586
static struct parport_driver cpia_pp_driver = {
587
        "cpia_pp",
588
        cpia_pp_attach,
589
        cpia_pp_detach,
590
        NULL
591
};
592
 
593
int cpia_pp_init(void)
594
{
595
        printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
596
               CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
597
 
598
        if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
599
                printk("  disabled\n");
600
                return 0;
601
        }
602
 
603
        spin_lock_init( &cam_list_lock_pp );
604
 
605
        if (parport_register_driver (&cpia_pp_driver)) {
606
                LOG ("unable to register with parport\n");
607
                return -EIO;
608
        }
609
        return 0;
610
}
611
 
612
#ifdef MODULE
613
int init_module(void)
614
{
615
        if (parport[0]) {
616
                /* The user gave some parameters.  Let's see what they were. */
617
                if (!strncmp(parport[0], "auto", 4)) {
618
                        parport_nr[0] = PPCPIA_PARPORT_AUTO;
619
                } else {
620
                        int n;
621
                        for (n = 0; n < PARPORT_MAX && parport[n]; n++) {
622
                                if (!strncmp(parport[n], "none", 4)) {
623
                                        parport_nr[n] = PPCPIA_PARPORT_NONE;
624
                                } else {
625
                                        char *ep;
626
                                        unsigned long r = simple_strtoul(parport[n], &ep, 0);
627
                                        if (ep != parport[n]) {
628
                                                parport_nr[n] = r;
629
                                        } else {
630
                                                LOG("bad port specifier `%s'\n", parport[n]);
631
                                                return -ENODEV;
632
                                        }
633
                                }
634
                        }
635
                }
636
        }
637
#if defined(CONFIG_KMOD) && defined(CONFIG_PNP_PARPORT_MODULE)
638
        if(parport_enumerate() && !parport_enumerate()->probe_info.model) {
639
                request_module("parport_probe");
640
        }
641
#endif
642
        return cpia_pp_init();
643
}
644
 
645
void cleanup_module(void)
646
{
647
        parport_unregister_driver (&cpia_pp_driver);
648
        return;
649
}
650
 
651
#else /* !MODULE */
652
 
653
static int __init cpia_pp_setup(char *str)
654
{
655
        if (!strncmp(str, "parport", 7)) {
656
                int n = simple_strtoul(str + 7, NULL, 10);
657
                if (parport_ptr < PARPORT_MAX) {
658
                        parport_nr[parport_ptr++] = n;
659
                } else {
660
                        LOG("too many ports, %s ignored.\n", str);
661
                }
662
        } else if (!strcmp(str, "auto")) {
663
                parport_nr[0] = PPCPIA_PARPORT_AUTO;
664
        } else if (!strcmp(str, "none")) {
665
                parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
666
        }
667
 
668
        return 0;
669
}
670
 
671
__setup("cpia_pp=", cpia_pp_setup);
672
 
673
#endif /* !MODULE */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.