diff options
Diffstat (limited to 'drivers/staging/dt3155')
-rw-r--r-- | drivers/staging/dt3155/Kconfig | 4 | ||||
-rw-r--r-- | drivers/staging/dt3155/Makefile | 6 | ||||
-rw-r--r-- | drivers/staging/dt3155/TODO | 10 | ||||
-rw-r--r-- | drivers/staging/dt3155/allocator.README | 98 | ||||
-rw-r--r-- | drivers/staging/dt3155/allocator.c | 294 | ||||
-rw-r--r-- | drivers/staging/dt3155/allocator.h | 28 | ||||
-rw-r--r-- | drivers/staging/dt3155/dt3155.h | 161 | ||||
-rw-r--r-- | drivers/staging/dt3155/dt3155.sysvinit | 60 | ||||
-rw-r--r-- | drivers/staging/dt3155/dt3155_drv.c | 1099 | ||||
-rw-r--r-- | drivers/staging/dt3155/dt3155_drv.h | 45 | ||||
-rw-r--r-- | drivers/staging/dt3155/dt3155_io.c | 165 | ||||
-rw-r--r-- | drivers/staging/dt3155/dt3155_io.h | 358 | ||||
-rw-r--r-- | drivers/staging/dt3155/dt3155_isr.c | 509 | ||||
-rw-r--r-- | drivers/staging/dt3155/dt3155_isr.h | 77 |
14 files changed, 0 insertions, 2914 deletions
diff --git a/drivers/staging/dt3155/Kconfig b/drivers/staging/dt3155/Kconfig deleted file mode 100644 index 4a3293c721b1..000000000000 --- a/drivers/staging/dt3155/Kconfig +++ /dev/null @@ -1,4 +0,0 @@ -config DT3155 - tristate "DT3155 Digitizer support" - depends on PCI - diff --git a/drivers/staging/dt3155/Makefile b/drivers/staging/dt3155/Makefile deleted file mode 100644 index 136f21fdbbee..000000000000 --- a/drivers/staging/dt3155/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -obj-$(CONFIG_DT3155) += dt3155.o -dt3155-objs := \ - dt3155_drv.o \ - dt3155_isr.o \ - dt3155_io.o \ - allocator.o diff --git a/drivers/staging/dt3155/TODO b/drivers/staging/dt3155/TODO deleted file mode 100644 index 3baa3b6294cc..000000000000 --- a/drivers/staging/dt3155/TODO +++ /dev/null @@ -1,10 +0,0 @@ -TODO: - - fix checkpatch.pl issues - - remove old kernel support, it is not needed - - convert to proper PCI device API - - fix sparse warnings - - audit for correct subsystem interaction - - review review review! - -Please send patches to Greg Kroah-Hartman <greg@kroah.com> -and Scott Smedley <ss@aao.gov.au> diff --git a/drivers/staging/dt3155/allocator.README b/drivers/staging/dt3155/allocator.README deleted file mode 100644 index 05700b6c926c..000000000000 --- a/drivers/staging/dt3155/allocator.README +++ /dev/null @@ -1,98 +0,0 @@ - -The allocator shown here exploits high memory. This document explains -how a user can deal with drivers uses this allocator and how a -programmer can link in the module. - -The module is being used by my pxc and pxdrv device drivers (as well as -other ones), available from ftp.systemy.it/pub/develop and -ftp.linux.it/pub/People/Rubini - - User's manual - ============= - - -One of the most compelling problems with any DMA-capable device is the -allocation of a suitable memory buffer. The "allocator" module tries -to deal with the problem in a clean way. The module is able to use -high memory (above the one used in normal operation) for DMA -allocation. - -To prevent the kernel for using high memory, so that it remains -available for DMA, you should pass a command line argument to the -kernel. Command line arguments can be passed to Lilo, to Loadlin or -to whichever loader you are using (unless it's very poor in design). -For Lilo, either use "append=" in /etc/lilo.conf or add commandline -arguments to the interactive prompt. For example, I have a 32MB box -and reserve two megs for DMA: - -In lilo.conf: - image = /zImage - label = linux - append = "mem=30M" - -Or, interactively: - LILO: linux mem=30M - -Once the kernel is booted with the right command-line argument, any -driver linked with the allocator module will be able to get -DMA-capable memory without much trouble (unless the various drivers -need more memory than available). - -The module implements an alloc/free mechanism, so that it can serve -multiple drivers at the same time. Note however that the allocator -uses all of high memory and assumes to be the only piece of software -using such memory. - - - Programmer's manual - =================== - -The allocator, as released, is designed to be linked to a device -driver. In this case, the driver must call allocator_init() before -using the allocator and must call allocator_cleanup() before -unloading. This is usually done from within init_module() and -cleanup_module(). If the allocator is linked to a driver, it won't be -possible for several drivers to allocate high DMA memory, as explained -above. - -It is possible, on the other hand, to compile the module as a standalone -module, so that several modules can rely on the allocator for they DMA -buffers. To compile the allocator as a standalone module, do the -following in this directory (or provide a suitable Makefile, or edit -the source code): - - make allocator.o CC="gcc -Dallocator_init=init_module -Dallocator_cleanup=cleanup_module -include /usr/include/linux/module.h" - -The previous commandline tells to include <linux/module.h> in the -first place, and to rename the init and cleanup function to the ones -needed for module loading and unloading. Drivers using a standalone -allocator won't need to call allocator_init() nor allocator_cleanup(). - -The allocator exports the following functions (declared in allocator.h): - - unsigned long allocator_allocate_dma (unsigned long kilobytes, - int priority); - - This function returns a physical address, over high_memory, - which corresponds to an area of at least "kilobytes" kilobytes. - The area will be owned by the module calling the function. - The returned address can be passed to device boards, to instruct - their DMA controllers, via phys_to_bus(). The address can be used - by C code after vremap()/ioremap(). The "priority" argument should - be GFP_KERNEL or GFP_ATOMIC, according to the context of the - caller; it is used to call kmalloc(), as the allocator must keep - track of any region it gives away. In case of error the function - returns 0, and the caller is expected to issue a -ENOMEM error. - - - void allocator_free_dma (unsigned long address); - - This function is the reverse of the previous one. If a driver - doesn't free the DMA memory it allocated, the allocator will - consider such memory as busy. Note, however, that - allocator_cleanup() calls kfree() on every region it reclaimed, - so that a driver with the allocator linked in can avoid calling - allocator_free_dma() at unload time. - - - diff --git a/drivers/staging/dt3155/allocator.c b/drivers/staging/dt3155/allocator.c deleted file mode 100644 index d33947b0378f..000000000000 --- a/drivers/staging/dt3155/allocator.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * allocator.c -- allocate after high_memory, if available - * - * NOTE: this is different from my previous allocator, the one that - * assembles pages, which revealed itself both slow and unreliable. - * - * Copyright (C) 1998 rubini@linux.it (Alessandro Rubini) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - --- Changes -- - - Date Programmer Description of changes made - ------------------------------------------------------------------- - 02-Aug-2002 NJC allocator now steps in 1MB increments, rather - than doubling its size each time. - Also, allocator_init(u32 *) now returns - (in the first arg) the size of the free - space. This is no longer consistent with - using the allocator as a module, and some changes - may be necessary for that purpose. This was - designed to work with the DT3155 driver, in - stand alone mode only!!! - 26-Oct-2009 SS Port to 2.6.30 kernel. - */ - - -#ifndef __KERNEL__ -# define __KERNEL__ -#endif -#ifndef MODULE -# define MODULE -#endif - - -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/proc_fs.h> -#include <linux/errno.h> -#include <linux/types.h> -#include <linux/mm.h> /* PAGE_ALIGN() */ -#include <linux/io.h> -#include <linux/slab.h> - -#include <asm/page.h> - -#include "allocator.h" - -/*#define ALL_DEBUG*/ -#define ALL_MSG "allocator: " - -#undef PDEBUG /* undef it, just in case */ -#ifdef ALL_DEBUG -# define __static -# define DUMP_LIST() dump_list() -# ifdef __KERNEL__ - /* This one if debugging is on, and kernel space */ -# define PDEBUG(fmt, args...) printk(KERN_DEBUG ALL_MSG fmt, ## args) -# else - /* This one for user space */ -# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) -# endif -#else -# define PDEBUG(fmt, args...) /* not debugging: nothing */ -# define DUMP_LIST() -# define __static static -#endif - -#undef PDEBUGG -#define PDEBUGG(fmt, args...) -/*#define PDEBUGG(fmt, args...) printk( KERN_DEBUG ALL_MSG fmt, ## args)*/ - - -static int allocator_himem = 1; /* 0 = probe, pos. = megs, neg. = disable */ -static int allocator_step = 1; /* This is the step size in MB */ -static int allocator_probe = 1; /* This is a flag -- 1=probe, 0=don't probe */ - -static unsigned long allocator_buffer; /* physical address */ -static unsigned long allocator_buffer_size; /* kilobytes */ - -/* - * The allocator keeps a list of DMA areas, so multiple devices - * can coexist. The list is kept sorted by address - */ - -struct allocator_struct { - unsigned long address; - unsigned long size; - struct allocator_struct *next; -}; - -static struct allocator_struct *allocator_list; - -#ifdef ALL_DEBUG -static int dump_list(void) -{ - struct allocator_struct *ptr; - - PDEBUG("Current list:\n"); - for (ptr = allocator_list; ptr; ptr = ptr->next) - PDEBUG("0x%08lx (size %likB)\n", ptr->address, ptr->size>>10); - return 0; -} -#endif - -/* ======================================================================== - * This function is the actual allocator. - * - * If space is available in high memory (as detected at load time), that - * one is returned. The return value is a physical address (i.e., it can - * be used straight ahead for DMA, but needs remapping for program use). - */ - -unsigned long allocator_allocate_dma(unsigned long kilobytes, gfp_t flags) -{ - struct allocator_struct *ptr = allocator_list, *newptr; - unsigned long bytes = kilobytes << 10; - - /* check if high memory is available */ - if (!allocator_buffer) - return 0; - - /* Round it to a multiple of the pagesize */ - bytes = PAGE_ALIGN(bytes); - PDEBUG("request for %li bytes\n", bytes); - - while (ptr && ptr->next) { - if (ptr->next->address - (ptr->address + ptr->size) >= bytes) - break; /* enough space */ - ptr = ptr->next; - } - if (!ptr->next) { - DUMP_LIST(); - PDEBUG("alloc failed\n"); - return 0; /* end of list */ - } - newptr = kmalloc(sizeof(struct allocator_struct), flags); - if (!newptr) - return 0; - - /* ok, now stick it after ptr */ - newptr->address = ptr->address + ptr->size; - newptr->size = bytes; - newptr->next = ptr->next; - ptr->next = newptr; - - DUMP_LIST(); - PDEBUG("returning 0x%08lx\n", newptr->address); - return newptr->address; -} - -int allocator_free_dma(unsigned long address) -{ - struct allocator_struct *ptr = allocator_list, *prev; - - while (ptr && ptr->next) { - if (ptr->next->address == address) - break; - ptr = ptr->next; - } - /* the one being freed is ptr->next */ - prev = ptr; ptr = ptr->next; - - if (!ptr) { - pr_err(ALL_MSG "free_dma but add. not allocated\n"); - return -EINVAL; - } - PDEBUGG("freeing: %08lx (%li) next %08lx\n", ptr->address, ptr->size, - ptr->next->address); - prev->next = ptr->next; - kfree(ptr); - - /* dump_list(); */ - return 0; -} - -/* ======================================================================== - * Init and cleanup - * - * On cleanup everything is released. If the list is not empty, that a - * problem of our clients - */ -int allocator_init(u32 *allocator_max) -{ - /* check how much free memory is there */ - void *remapped; - unsigned long max; - unsigned long trial_size = allocator_himem<<20; - unsigned long last_trial = 0; - unsigned long step = allocator_step<<20; - unsigned long i = 0; - struct allocator_struct *head, *tail; - char test_string[] = "0123456789abcde"; /* 16 bytes */ - - PDEBUGG("himem = %i\n", allocator_himem); - if (allocator_himem < 0) /* don't even try */ - return -EINVAL; - - if (!trial_size) - trial_size = 1<<20; /* not specified: try one meg */ - - while (1) { - remapped = ioremap(__pa(high_memory), trial_size); - if (!remapped) { - PDEBUGG("%li megs failed!\n", trial_size>>20); - break; - } - PDEBUGG("Trying %li megs (at %p, %p)\n", trial_size>>20, - (void *)__pa(high_memory), remapped); - for (i = last_trial; i < trial_size; i += 16) { - strcpy((char *)(remapped)+i, test_string); - if (strcmp((char *)(remapped)+i, test_string)) - break; - } - iounmap((void *)remapped); - schedule(); - last_trial = trial_size; - if (i == trial_size) - trial_size += step; /* increment, if all went well */ - else { - PDEBUGG("%li megs copy test failed!\n", trial_size>>20); - break; - } - if (!allocator_probe) - break; - } - PDEBUG("%li megs (%li k, %li b)\n", i>>20, i>>10, i); - allocator_buffer_size = i>>10; /* kilobytes */ - allocator_buffer = __pa(high_memory); - if (!allocator_buffer_size) { - printk(KERN_WARNING ALL_MSG "no free high memory to use\n"); - return -ENOMEM; - } - - /* - * to simplify things, always have two cells in the list: - * the first and the last. This avoids some conditionals and - * extra code when allocating and deallocating: we only play - * in the middle of the list - */ - head = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL); - if (!head) - return -ENOMEM; - tail = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL); - if (!tail) { - kfree(head); - return -ENOMEM; - } - - max = allocator_buffer_size<<10; - - head->size = tail->size = 0; - head->address = allocator_buffer; - tail->address = allocator_buffer + max; - head->next = tail; - tail->next = NULL; - allocator_list = head; - - /* Back to the user code, in KB */ - *allocator_max = allocator_buffer_size; - - return 0; /* ok, ready */ -} - -void allocator_cleanup(void) -{ - struct allocator_struct *ptr, *next; - - for (ptr = allocator_list; ptr; ptr = next) { - next = ptr->next; - PDEBUG("freeing list: 0x%08lx\n", ptr->address); - kfree(ptr); - } - - allocator_buffer = 0; - allocator_buffer_size = 0; - allocator_list = NULL; -} - - diff --git a/drivers/staging/dt3155/allocator.h b/drivers/staging/dt3155/allocator.h deleted file mode 100644 index 425b70fcd500..000000000000 --- a/drivers/staging/dt3155/allocator.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * allocator.h -- prototypes for allocating high memory - * - * NOTE: this is different from my previous allocator, the one that - * assembles pages, which revealed itself both slow and unreliable. - * - * Copyright (C) 1998 rubini@linux.it (Alessandro Rubini) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -int allocator_free_dma(unsigned long address); -unsigned long allocator_allocate_dma(unsigned long kilobytes, gfp_t flags); -int allocator_init(u32 *); -void allocator_cleanup(void); diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h deleted file mode 100644 index 793e2fcf4466..000000000000 --- a/drivers/staging/dt3155/dt3155.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - -Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, - Jason Lapenta, Scott Smedley - -This file is part of the DT3155 Device Driver. - -The DT3155 Device Driver is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The DT3155 Device Driver is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty -of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the DT3155 Device Driver; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307 USA - --- Changes -- - - Date Programmer Description of changes made - ------------------------------------------------------------------- - 03-Jul-2000 JML n/a - 10-Oct-2001 SS port to 2.4 kernel. - 24-Jul-2002 SS remove unused code & added GPL licence. - 05-Aug-2005 SS port to 2.6 kernel; make CCIR mode default. - -*/ - -#ifndef _DT3155_INC -#define _DT3155_INC - -#include <linux/types.h> -#include <linux/time.h> /* struct timeval */ - - -/* Uncomment this for 50Hz CCIR */ -#define CCIR 1 - -/* Can be 1 or 2 */ -#define MAXBOARDS 1 - -#define BOARD_MAX_BUFFS 3 -#define MAXBUFFERS (BOARD_MAX_BUFFS*MAXBOARDS) - -#define PCI_PAGE_SIZE (1 << 12) - -#ifdef CCIR -#define DT3155_MAX_ROWS 576 -#define DT3155_MAX_COLS 768 -#define FORMAT50HZ 1 -#else -#define DT3155_MAX_ROWS 480 -#define DT3155_MAX_COLS 640 -#define FORMAT50HZ 0 -#endif - -/* Configuration structure */ -struct dt3155_config { - u32 acq_mode; - u32 cols, rows; - u32 continuous; -}; - - -/* hold data for each frame */ -struct frame_info { - u32 addr; /* address of the buffer with the frame */ - u32 tag; /* unique number for the frame */ - struct timeval time; /* time that capture took place */ -}; - -/* - * Structure for interrupt and buffer handling. - * This is the setup for 1 card - */ -struct dt3155_fbuffer { - int nbuffers; - - struct frame_info frame_info[BOARD_MAX_BUFFS]; - - int empty_buffers[BOARD_MAX_BUFFS]; /* indexes empty frames */ - int empty_len; /* Number of empty buffers */ - /* Zero means empty */ - - int active_buf; /* Where data is currently dma'ing */ - int locked_buf; /* Buffers used by user */ - - int ready_que[BOARD_MAX_BUFFS]; - u32 ready_head; /* The most recent buffer located here */ - u32 ready_len; /* The number of ready buffers */ - - int even_happened; - int even_stopped; - - int stop_acquire; /* Flag to stop interrupts */ - u32 frame_count; /* Counter for frames acquired by this card */ -}; - - - -#define DT3155_MODE_FRAME 1 -#define DT3155_MODE_FIELD 2 - -#define DT3155_SNAP 1 -#define DT3155_ACQ 2 - -/* There is one status structure for each card. */ -struct dt3155_status { - int fixed_mode; /* if 1, we are in fixed frame mode */ - u32 reg_addr; /* Register address for a single card */ - u32 mem_addr; /* Buffer start addr for this card */ - u32 mem_size; /* This is the amount of mem available */ - u32 irq; /* this card's irq */ - struct dt3155_config config; /* configuration struct */ - struct dt3155_fbuffer fbuffer; /* frame buffer state struct */ - u32 state; /* this card's state */ - u32 device_installed; /* Flag if installed. 1=installed */ -}; - -/* Reference to global status structure */ -extern struct dt3155_status dt3155_status[MAXBOARDS]; - -#define DT3155_STATE_IDLE 0x00 -#define DT3155_STATE_FRAME 0x01 -#define DT3155_STATE_FLD 0x02 -#define DT3155_STATE_STOP 0x100 -#define DT3155_STATE_ERROR 0x200 -#define DT3155_STATE_MODE 0x0ff - -#define DT3155_IOC_MAGIC '!' - -#define DT3155_SET_CONFIG _IOW(DT3155_IOC_MAGIC, 1, struct dt3155_config) -#define DT3155_GET_CONFIG _IOR(DT3155_IOC_MAGIC, 2, struct dt3155_status) -#define DT3155_STOP _IO(DT3155_IOC_MAGIC, 3) -#define DT3155_START _IO(DT3155_IOC_MAGIC, 4) -#define DT3155_FLUSH _IO(DT3155_IOC_MAGIC, 5) -#define DT3155_IOC_MAXNR 5 - -/* Error codes */ - -#define DT_ERR_NO_BUFFERS 0x10000 /* not used but it might be one day */ -#define DT_ERR_CORRUPT 0x20000 -#define DT_ERR_OVERRUN 0x30000 -#define DT_ERR_I2C_TIMEOUT 0x40000 -#define DT_ERR_MASK 0xff0000/* not used but it might be one day */ - -/* User code will probably want to declare one of these for each card */ -struct dt3155_read { - u32 offset; - u32 frame_seq; - u32 state; - - struct frame_info frame_info; -}; - -#endif /* _DT3155_inc */ diff --git a/drivers/staging/dt3155/dt3155.sysvinit b/drivers/staging/dt3155/dt3155.sysvinit deleted file mode 100644 index 92ec0939cb7a..000000000000 --- a/drivers/staging/dt3155/dt3155.sysvinit +++ /dev/null @@ -1,60 +0,0 @@ -#! /bin/sh -# -# Module load/unload script for use with SysV-style /etc/init.d/ systems. -# On a Debian system, copy this to /etc/init.d/dt3155 and then run -# /usr/sbin/update-rc.d dt3155 defaults 55 -# to create the appropriate /etc/rc?.d/[SK]55dt3155 start/stop links. -# (The "55" is arbitrary but is what I use to load this rather late.) -# -# Andy Dougherty Feb 22 2000 doughera@lafayette.edu -# Dept. of Physics -# Lafayette College, Easton PA 18042 -# - -PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin - -# Edit to point to your local copy. -FILE=/usr/local/lib/modules/dt3155/dt3155.o -NAME="dt3155" -DESC="dt3155 Frame Grabber module" -DEV="dt3155" - -if test ! -f $FILE; then - echo "Unable to locate $FILE" - exit 0 -fi - -set -e - -case "$1" in - start) - echo -n "Loading $DESC " - if /sbin/insmod -v -f $FILE; then - major=`grep $DEV /proc/devices | awk "{print \\$1}"` - rm -f /dev/dt3155? - mknod /dev/dt3155a c $major 0 - mknod /dev/dt3155b c $major 1 - chmod go+rw /dev/dt3155? - echo - else - echo "$FILE not loaded." - fi - ;; - stop) - echo -n "Unloading $DESC: " - if /sbin/rmmod $NAME ; then - echo - else - echo "$DEV not removed" - exit 0 - fi - rm -f /dev/dt3155? - ;; - *) - echo "Usage: /etc/init.d/$NAME {start|stop}" - exit 1 - ;; -esac - -exit 0 - diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c deleted file mode 100644 index 40ef97f3feb5..000000000000 --- a/drivers/staging/dt3155/dt3155_drv.c +++ /dev/null @@ -1,1099 +0,0 @@ -/* - -Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, - Jason Lapenta, Scott Smedley, Greg Sharp - -This file is part of the DT3155 Device Driver. - -The DT3155 Device Driver is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The DT3155 Device Driver is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty -of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the DT3155 Device Driver; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307 USA - --- Changes -- - - Date Programmer Description of changes made - ------------------------------------------------------------------- - 03-Jul-2000 JML n/a - 10-Oct-2001 SS port to 2.4 kernel - 02-Apr-2002 SS Mods to use allocator as a standalone module; - Merged John Roll's changes (john@cfa.harvard.edu) - to make work with multiple boards. - 02-Jul-2002 SS Merged James Rose's chages (rosejr@purdue.edu) to: - * fix successive interrupt-driven captures - * add select/poll support. - 10-Jul-2002 GCS Add error check when ndevices > MAXBOARDS. - 02-Aug-2002 GCS Fix field mode so that odd (lower) field is stored - in lower half of buffer. - 05-Aug-2005 SS port to 2.6 kernel. - 26-Oct-2009 SS port to 2.6.30 kernel. - --- Notes -- - -** appended "mem=124" in lilo.conf to allow for 4megs free on my 128meg system. - * using allocator.c and allocator.h from o'reilly book (alessandro rubini) - ftp://ftp.systemy.it/pub/develop (see README.allocator) - - + might want to get rid of MAXboards for allocating initial buffer. - confusing and not necessary - - + in cleanup_module the MOD_IN_USE looks like it is check after it should - - * GFP_DMA should not be set with a PCI system (pg 291) - - - NJC why are only two buffers allowed? (see isr, approx line 358) - -*/ - -extern void printques(int); - -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/types.h> -#include <linux/poll.h> -#include <linux/sched.h> -#include <linux/smp_lock.h> - -#include <asm/io.h> -#include <asm/uaccess.h> - -#include "dt3155.h" -#include "dt3155_drv.h" -#include "dt3155_isr.h" -#include "dt3155_io.h" -#include "allocator.h" - - -MODULE_LICENSE("GPL"); - -/* Error variable. Zero means no error. */ -int dt3155_errno = 0; - -#ifndef PCI_DEVICE_ID_INTEL_7116 -#define PCI_DEVICE_ID_INTEL_7116 0x1223 -#endif - -#define DT3155_VENDORID PCI_VENDOR_ID_INTEL -#define DT3155_DEVICEID PCI_DEVICE_ID_INTEL_7116 -#define MAXPCI 16 - -#ifdef DT_DEBUG -#define DT_3155_DEBUG_MSG(x,y) printk(x,y) -#else -#define DT_3155_DEBUG_MSG(x,y) -#endif - -/* wait queue for interrupts */ -wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS]; - -#define DT_3155_SUCCESS 0 -#define DT_3155_FAILURE -EIO - -/* set to dynamicaly allocate, but it is tunable: */ -/* insmod DT_3155 dt3155 dt3155_major=XX */ -int dt3155_major = 0; - -/* The minor numbers are 0 and 1 ... they are not tunable. - * They are used as the indices for the structure vectors, - * and register address vectors - */ - -/* Global structures and variables */ - -/* Status of each device */ -struct dt3155_status dt3155_status[MAXBOARDS]; - -/* kernel logical address of the board */ -u8 *dt3155_lbase[MAXBOARDS] = { NULL -#if MAXBOARDS == 2 - , NULL -#endif -}; -/* DT3155 registers */ -u8 *dt3155_bbase = NULL; /* kernel logical address of the * - * buffer region */ -u32 dt3155_dev_open[MAXBOARDS] = {0 -#if MAXBOARDS == 2 - , 0 -#endif -}; - -u32 ndevices = 0; -u32 unique_tag = 0;; - - -/* - * Stops interrupt generation right away and resets the status - * to idle. I don't know why this works and the other way doesn't. - * (James Rose) - */ -static void quick_stop (int minor) -{ - // TODO: scott was here -#if 1 - ReadMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); - /* disable interrupts */ - int_csr_r.fld.FLD_END_EVE_EN = 0; - int_csr_r.fld.FLD_END_ODD_EN = 0; - WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); - - dt3155_status[minor].state &= ~(DT3155_STATE_STOP|0xff); - /* mark the system stopped: */ - dt3155_status[minor].state |= DT3155_STATE_IDLE; - dt3155_fbuffer[minor]->stop_acquire = 0; - dt3155_fbuffer[minor]->even_stopped = 0; -#else - dt3155_status[minor].state |= DT3155_STATE_STOP; - dt3155_status[minor].fbuffer.stop_acquire = 1; -#endif - -} - - -/***************************************************** - * dt3155_isr() Interrupt service routien - * - * - looks like this isr supports IRQ sharing (or could) JML - * - Assumes irq's are disabled, via SA_INTERRUPT flag - * being set in request_irq() call from init_module() - *****************************************************/ -static void dt3155_isr(int irq, void *dev_id, struct pt_regs *regs) -{ - int minor = -1; - int index; - unsigned long flags; - u32 buffer_addr; - - /* find out who issued the interrupt */ - for (index = 0; index < ndevices; index++) { - if(dev_id == (void*) &dt3155_status[index]) - { - minor = index; - break; - } - } - - /* hopefully we should not get here */ - if (minor < 0 || minor >= MAXBOARDS) { - printk(KERN_ERR "dt3155_isr called with invalid dev_id\n"); - return; - } - - /* Check for corruption and set a flag if so */ - ReadMReg((dt3155_lbase[minor] + CSR1), csr1_r.reg); - - if ((csr1_r.fld.FLD_CRPT_EVE) || (csr1_r.fld.FLD_CRPT_ODD)) - { - /* TODO: this should probably stop acquisition */ - /* and set some flags so that dt3155_read */ - /* returns an error next time it is called */ - dt3155_errno = DT_ERR_CORRUPT; - printk("dt3155: corrupt field\n"); - return; - } - - ReadMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); - - /* Handle the even field ... */ - if (int_csr_r.fld.FLD_END_EVE) - { - if ((dt3155_status[minor].state & DT3155_STATE_MODE) == - DT3155_STATE_FLD) - { - dt3155_fbuffer[minor]->frame_count++; - } - - ReadI2C(dt3155_lbase[minor], EVEN_CSR, &i2c_even_csr.reg); - - /* Clear the interrupt? */ - int_csr_r.fld.FLD_END_EVE = 1; - - /* disable the interrupt if last field */ - if (dt3155_fbuffer[minor]->stop_acquire) - { - printk("dt3155: even stopped.\n"); - dt3155_fbuffer[minor]->even_stopped = 1; - if (i2c_even_csr.fld.SNGL_EVE) - { - int_csr_r.fld.FLD_END_EVE_EN = 0; - } - else - { - i2c_even_csr.fld.SNGL_EVE = 1; - } - } - - WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); - - /* Set up next DMA if we are doing FIELDS */ - if ((dt3155_status[minor].state & DT3155_STATE_MODE) == - DT3155_STATE_FLD) - { - /* GCS (Aug 2, 2002) -- In field mode, dma the odd field - into the lower half of the buffer */ - const u32 stride = dt3155_status[minor].config.cols; - buffer_addr = dt3155_fbuffer[minor]-> - frame_info[dt3155_fbuffer[minor]->active_buf].addr - + (DT3155_MAX_ROWS / 2) * stride; - local_save_flags(flags); - local_irq_disable(); - wake_up_interruptible(&dt3155_read_wait_queue[minor]); - - /* Set up the DMA address for the next field */ - local_irq_restore(flags); - WriteMReg((dt3155_lbase[minor] + ODD_DMA_START), buffer_addr); - } - - /* Check for errors. */ - i2c_even_csr.fld.DONE_EVE = 1; - if (i2c_even_csr.fld.ERROR_EVE) - dt3155_errno = DT_ERR_OVERRUN; - - WriteI2C(dt3155_lbase[minor], EVEN_CSR, i2c_even_csr.reg); - - /* Note that we actually saw an even field meaning */ - /* that subsequent odd field complete the frame */ - dt3155_fbuffer[minor]->even_happened = 1; - - /* recording the time that the even field finished, this should be */ - /* about time in the middle of the frame */ - do_gettimeofday(&(dt3155_fbuffer[minor]-> - frame_info[dt3155_fbuffer[minor]-> - active_buf].time)); - return; - } - - /* ... now handle the odd field */ - if (int_csr_r.fld.FLD_END_ODD) - { - ReadI2C(dt3155_lbase[minor], ODD_CSR, &i2c_odd_csr.reg); - - /* Clear the interrupt? */ - int_csr_r.fld.FLD_END_ODD = 1; - - if (dt3155_fbuffer[minor]->even_happened || - (dt3155_status[minor].state & DT3155_STATE_MODE) == - DT3155_STATE_FLD) - { - dt3155_fbuffer[minor]->frame_count++; - } - - if (dt3155_fbuffer[minor]->stop_acquire && - dt3155_fbuffer[minor]->even_stopped) - { - printk(KERN_DEBUG "dt3155: stopping odd..\n"); - if (i2c_odd_csr.fld.SNGL_ODD) - { - /* disable interrupts */ - int_csr_r.fld.FLD_END_ODD_EN = 0; - dt3155_status[minor].state &= ~(DT3155_STATE_STOP|0xff); - - /* mark the system stopped: */ - dt3155_status[minor].state |= DT3155_STATE_IDLE; - dt3155_fbuffer[minor]->stop_acquire = 0; - dt3155_fbuffer[minor]->even_stopped = 0; - - printk(KERN_DEBUG "dt3155: state is now %x\n", - dt3155_status[minor].state); - } - else - { - i2c_odd_csr.fld.SNGL_ODD = 1; - } - } - - WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); - - /* if the odd field has been acquired, then */ - /* change the next dma location for both fields */ - /* and wake up the process if sleeping */ - if (dt3155_fbuffer[minor]->even_happened || - (dt3155_status[minor].state & DT3155_STATE_MODE) == - DT3155_STATE_FLD) - { - - local_save_flags(flags); - local_irq_disable(); - -#ifdef DEBUG_QUES_B - printques(minor); -#endif - if (dt3155_fbuffer[minor]->nbuffers > 2) - { - if (!are_empty_buffers(minor)) - { - /* The number of active + locked buffers is - * at most 2, and since there are none empty, there - * must be at least nbuffers-2 ready buffers. - * This is where we 'drop frames', oldest first. */ - push_empty(pop_ready(minor), minor); - } - - /* The ready_que can't be full, since we know - * there is one active buffer right now, so it's safe - * to push the active buf on the ready_que. */ - push_ready(minor, dt3155_fbuffer[minor]->active_buf); - /* There's at least 1 empty -- make it active */ - dt3155_fbuffer[minor]->active_buf = pop_empty(minor); - dt3155_fbuffer[minor]-> - frame_info[dt3155_fbuffer[minor]-> - active_buf].tag = ++unique_tag; - } - else /* nbuffers == 2, special case */ - { /* There is 1 active buffer. - * If there is a locked buffer, keep the active buffer - * the same -- that means we drop a frame. - */ - if (dt3155_fbuffer[minor]->locked_buf < 0) - { - push_ready(minor, - dt3155_fbuffer[minor]->active_buf); - if (are_empty_buffers(minor)) - { - dt3155_fbuffer[minor]->active_buf = - pop_empty(minor); - } - else - { /* no empty or locked buffers, so use a readybuf */ - dt3155_fbuffer[minor]->active_buf = - pop_ready(minor); - } - } - } - -#ifdef DEBUG_QUES_B - printques(minor); -#endif - - dt3155_fbuffer[minor]->even_happened = 0; - - wake_up_interruptible(&dt3155_read_wait_queue[minor]); - - local_irq_restore(flags); - } - - - /* Set up the DMA address for the next frame/field */ - buffer_addr = dt3155_fbuffer[minor]-> - frame_info[dt3155_fbuffer[minor]->active_buf].addr; - if ((dt3155_status[minor].state & DT3155_STATE_MODE) == - DT3155_STATE_FLD) - { - WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), buffer_addr); - } - else - { - WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), buffer_addr); - - WriteMReg((dt3155_lbase[minor] + ODD_DMA_START), buffer_addr - + dt3155_status[minor].config.cols); - } - - /* Do error checking */ - i2c_odd_csr.fld.DONE_ODD = 1; - if (i2c_odd_csr.fld.ERROR_ODD) - dt3155_errno = DT_ERR_OVERRUN; - - WriteI2C(dt3155_lbase[minor], ODD_CSR, i2c_odd_csr.reg); - - return; - } - /* If we get here, the Odd Field wasn't it either... */ - printk("neither even nor odd. shared perhaps?\n"); -} - -/***************************************************** - * init_isr(int minor) - * turns on interupt generation for the card - * designated by "minor". - * It is called *only* from inside ioctl(). - *****************************************************/ -static void dt3155_init_isr(int minor) -{ - const u32 stride = dt3155_status[minor].config.cols; - - switch (dt3155_status[minor].state & DT3155_STATE_MODE) - { - case DT3155_STATE_FLD: - { - even_dma_start_r = dt3155_status[minor]. - fbuffer.frame_info[dt3155_status[minor].fbuffer.active_buf].addr; - even_dma_stride_r = 0; - odd_dma_stride_r = 0; - - WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), - even_dma_start_r); - WriteMReg((dt3155_lbase[minor] + EVEN_DMA_STRIDE), - even_dma_stride_r); - WriteMReg((dt3155_lbase[minor] + ODD_DMA_STRIDE), - odd_dma_stride_r); - break; - } - - case DT3155_STATE_FRAME: - default: - { - even_dma_start_r = dt3155_status[minor]. - fbuffer.frame_info[dt3155_status[minor].fbuffer.active_buf].addr; - odd_dma_start_r = even_dma_start_r + stride; - even_dma_stride_r = stride; - odd_dma_stride_r = stride; - - WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), - even_dma_start_r); - WriteMReg((dt3155_lbase[minor] + ODD_DMA_START), - odd_dma_start_r); - WriteMReg((dt3155_lbase[minor] + EVEN_DMA_STRIDE), - even_dma_stride_r); - WriteMReg((dt3155_lbase[minor] + ODD_DMA_STRIDE), - odd_dma_stride_r); - break; - } - } - - /* 50/60 Hz should be set before this point but let's make sure it is */ - /* right anyway */ - - ReadI2C(dt3155_lbase[minor], CSR2, &i2c_csr2.reg); - i2c_csr2.fld.HZ50 = FORMAT50HZ; - WriteI2C(dt3155_lbase[minor], CSR2, i2c_csr2.reg); - - /* enable busmaster chip, clear flags */ - - /* - * TODO: - * shouldn't we be concered with continuous values of - * DT3155_SNAP & DT3155_ACQ here? (SS) - */ - - csr1_r.reg = 0; - csr1_r.fld.CAP_CONT_EVE = 1; /* use continuous capture bits to */ - csr1_r.fld.CAP_CONT_ODD = 1; /* enable */ - csr1_r.fld.FLD_DN_EVE = 1; /* writing a 1 clears flags */ - csr1_r.fld.FLD_DN_ODD = 1; - csr1_r.fld.SRST = 1; /* reset - must be 1 */ - csr1_r.fld.FIFO_EN = 1; /* fifo control - must be 1 */ - csr1_r.fld.FLD_CRPT_EVE = 1; /* writing a 1 clears flags */ - csr1_r.fld.FLD_CRPT_ODD = 1; - - WriteMReg((dt3155_lbase[minor] + CSR1),csr1_r.reg); - - /* Enable interrupts at the end of each field */ - - int_csr_r.reg = 0; - int_csr_r.fld.FLD_END_EVE_EN = 1; - int_csr_r.fld.FLD_END_ODD_EN = 1; - int_csr_r.fld.FLD_START_EN = 0; - - WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); - - /* start internal BUSY bits */ - - ReadI2C(dt3155_lbase[minor], CSR2, &i2c_csr2.reg); - i2c_csr2.fld.BUSY_ODD = 1; - i2c_csr2.fld.BUSY_EVE = 1; - WriteI2C(dt3155_lbase[minor], CSR2, i2c_csr2.reg); - - /* Now its up to the interrupt routine!! */ - - return; -} - - -/***************************************************** - * ioctl() - * - *****************************************************/ -static int dt3155_ioctl(struct inode *inode, - struct file *file, - unsigned int cmd, - unsigned long arg) -{ - int minor = MINOR(inode->i_rdev); /* What device are we ioctl()'ing? */ - - if (minor >= MAXBOARDS || minor < 0) - return -ENODEV; - - /* make sure it is valid command */ - if (_IOC_NR(cmd) > DT3155_IOC_MAXNR) - { - printk("DT3155: invalid IOCTL(0x%x)\n",cmd); - printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n", - (unsigned int)DT3155_GET_CONFIG, - (unsigned int)DT3155_SET_CONFIG, - (unsigned int)DT3155_START, - (unsigned int)DT3155_STOP, - (unsigned int)DT3155_FLUSH); - return -EINVAL; - } - - switch (cmd) - { - case DT3155_SET_CONFIG: - { - if (dt3155_status[minor].state != DT3155_STATE_IDLE) - return -EBUSY; - - { - struct dt3155_config tmp; - if (copy_from_user((void *)&tmp, (void *) arg, sizeof(tmp))) - return -EFAULT; - /* check for valid settings */ - if (tmp.rows > DT3155_MAX_ROWS || - tmp.cols > DT3155_MAX_COLS || - (tmp.acq_mode != DT3155_MODE_FRAME && - tmp.acq_mode != DT3155_MODE_FIELD) || - (tmp.continuous != DT3155_SNAP && - tmp.continuous != DT3155_ACQ)) - { - return -EINVAL; - } - dt3155_status[minor].config = tmp; - } - return 0; - } - case DT3155_GET_CONFIG: - { - if (copy_to_user((void *) arg, (void *) &dt3155_status[minor], - sizeof(struct dt3155_status))) - return -EFAULT; - return 0; - } - case DT3155_FLUSH: /* Flushes the buffers -- ensures fresh data */ - { - if (dt3155_status[minor].state != DT3155_STATE_IDLE) - return -EBUSY; - return dt3155_flush(minor); - } - case DT3155_STOP: - { - if (dt3155_status[minor].state & DT3155_STATE_STOP || - dt3155_status[minor].fbuffer.stop_acquire) - return -EBUSY; - - if (dt3155_status[minor].state == DT3155_STATE_IDLE) - return 0; - - quick_stop(minor); - if (copy_to_user((void *) arg, (void *) &dt3155_status[minor], - sizeof(struct dt3155_status))) - return -EFAULT; - return 0; - } - case DT3155_START: - { - if (dt3155_status[minor].state != DT3155_STATE_IDLE) - return -EBUSY; - - dt3155_status[minor].fbuffer.stop_acquire = 0; - dt3155_status[minor].fbuffer.frame_count = 0; - - /* Set the MODE in the status -- we default to FRAME */ - if (dt3155_status[minor].config.acq_mode == DT3155_MODE_FIELD) - { - dt3155_status[minor].state = DT3155_STATE_FLD; - } - else - { - dt3155_status[minor].state = DT3155_STATE_FRAME; - } - - dt3155_init_isr(minor); - if (copy_to_user((void *) arg, (void *) &dt3155_status[minor], - sizeof(struct dt3155_status))) - return -EFAULT; - return 0; - } - default: - { - printk("DT3155: invalid IOCTL(0x%x)\n",cmd); - printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n", - (unsigned int)DT3155_GET_CONFIG, - (unsigned int)DT3155_SET_CONFIG, - DT3155_START, DT3155_STOP, DT3155_FLUSH); - return -ENOSYS; - } - } - return -ENOSYS; -} - -/***************************************************** - * mmap() - * - * only allow the user to mmap the registers and buffer - * It is quite possible that this is broken, since the - * addition of of the capacity for two cards!!!!!!!! - * It *looks* like it should work but since I'm not - * sure how to use it, I'm not actually sure. (NJC? ditto by SS) - *****************************************************/ -static int dt3155_mmap (struct file * file, struct vm_area_struct * vma) -{ - /* which device are we mmapping? */ - int minor = MINOR(file->f_dentry->d_inode->i_rdev); - unsigned long offset; - offset = vma->vm_pgoff << PAGE_SHIFT; - - if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC)) - vma->vm_flags |= VM_IO; - - /* Don't try to swap out physical pages.. */ - vma->vm_flags |= VM_RESERVED; - - /* they are mapping the registers or the buffer */ - if ((offset == dt3155_status[minor].reg_addr && - vma->vm_end - vma->vm_start == PCI_PAGE_SIZE) || - (offset == dt3155_status[minor].mem_addr && - vma->vm_end - vma->vm_start == dt3155_status[minor].mem_size)) - { - if (remap_pfn_range(vma, - vma->vm_start, - offset >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) { - printk("DT3155: remap_page_range() failed.\n"); - return -EAGAIN; - } - } - else - { - printk("DT3155: dt3155_mmap() bad call.\n"); - return -ENXIO; - } - - return 0; -} - - -/***************************************************** - * open() - * - * Our special open code. - * MOD_INC_USE_COUNT make sure that the driver memory is not freed - * while the device is in use. - *****************************************************/ -static int dt3155_open(struct inode* inode, struct file* filep) -{ - int minor = MINOR(inode->i_rdev); /* what device are we opening? */ - if (dt3155_dev_open[minor]) { - printk ("DT3155: Already opened by another process.\n"); - return -EBUSY; - } - - if (dt3155_status[minor].device_installed==0) - { - printk("DT3155 Open Error: No such device dt3155 minor number %d\n", - minor); - return -EIO; - } - - if (dt3155_status[minor].state != DT3155_STATE_IDLE) { - printk ("DT3155: Not in idle state (state = %x)\n", - dt3155_status[minor].state); - return -EBUSY; - } - - printk("DT3155: Device opened.\n"); - - dt3155_dev_open[minor] = 1 ; - - dt3155_flush(minor); - - /* Disable ALL interrupts */ - int_csr_r.reg = 0; - WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); - - init_waitqueue_head(&(dt3155_read_wait_queue[minor])); - - return 0; -} - - -/***************************************************** - * close() - * - * Now decrement the use count. - * - *****************************************************/ -static int dt3155_close(struct inode *inode, struct file *filep) -{ - int minor; - - minor = MINOR(inode->i_rdev); /* which device are we closing */ - if (!dt3155_dev_open[minor]) - { - printk("DT3155: attempt to CLOSE a not OPEN device\n"); - } - else - { - dt3155_dev_open[minor] = 0; - - if (dt3155_status[minor].state != DT3155_STATE_IDLE) - { - quick_stop(minor); - } - } - return 0; -} - -/***************************************************** - * read() - * - *****************************************************/ -static ssize_t dt3155_read(struct file *filep, char __user *buf, - size_t count, loff_t *ppos) -{ - /* which device are we reading from? */ - int minor = MINOR(filep->f_dentry->d_inode->i_rdev); - u32 offset; - int frame_index; - struct frame_info *frame_info; - - /* TODO: this should check the error flag and */ - /* return an error on hardware failures */ - if (count != sizeof(struct dt3155_read)) - { - printk("DT3155 ERROR (NJC): count is not right\n"); - return -EINVAL; - } - - - /* Hack here -- I'm going to allow reading even when idle. - * this is so that the frames can be read after STOP has - * been called. Leaving it here, commented out, as a reminder - * for a short while to make sure there are no problems. - * Note that if the driver is not opened in non_blocking mode, - * and the device is idle, then it could sit here forever! */ - - /* if (dt3155_status[minor].state == DT3155_STATE_IDLE)*/ - /* return -EBUSY;*/ - - /* non-blocking reads should return if no data */ - if (filep->f_flags & O_NDELAY) - { - if ((frame_index = dt3155_get_ready_buffer(minor)) < 0) { - /*printk("dt3155: no buffers available (?)\n");*/ - /* printques(minor); */ - return -EAGAIN; - } - } - else - { - /* - * sleep till data arrives , or we get interrupted. - * Note that wait_event_interruptible() does not actually - * sleep/wait if it's condition evaluates to true upon entry. - */ - wait_event_interruptible(dt3155_read_wait_queue[minor], - (frame_index = dt3155_get_ready_buffer(minor)) - >= 0); - - if (frame_index < 0) - { - printk ("DT3155: read: interrupted\n"); - quick_stop (minor); - printques(minor); - return -EINTR; - } - } - - frame_info = &dt3155_status[minor].fbuffer.frame_info[frame_index]; - - /* make this an offset */ - offset = frame_info->addr - dt3155_status[minor].mem_addr; - - put_user(offset, (unsigned int *) buf); - buf += sizeof(u32); - put_user(dt3155_status[minor].fbuffer.frame_count, (unsigned int *) buf); - buf += sizeof(u32); - put_user(dt3155_status[minor].state, (unsigned int *) buf); - buf += sizeof(u32); - if (copy_to_user(buf, frame_info, sizeof(*frame_info))) - return -EFAULT; - - return sizeof(struct dt3155_read); -} - -static unsigned int dt3155_poll (struct file * filp, poll_table *wait) -{ - int minor = MINOR(filp->f_dentry->d_inode->i_rdev); - - if (!is_ready_buf_empty(minor)) - return POLLIN | POLLRDNORM; - - poll_wait (filp, &dt3155_read_wait_queue[minor], wait); - - return 0; -} - -static long -dt3155_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - int ret; - - lock_kernel(); - ret = dt3155_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); - unlock_kernel(); - - return ret; -} - -/***************************************************** - * file operations supported by DT3155 driver - * needed by init_module - * register_chrdev - *****************************************************/ -static struct file_operations dt3155_fops = { - .read = dt3155_read, - .unlocked_ioctl = dt3155_unlocked_ioctl, - .mmap = dt3155_mmap, - .poll = dt3155_poll, - .open = dt3155_open, - .release = dt3155_close -}; - - -/***************************************************** - * find_PCI(); - * - * PCI has been totally reworked in 2.1.. - *****************************************************/ -static int find_PCI (void) -{ - struct pci_dev *pci_dev = NULL; - int error, pci_index = 0; - unsigned short rev_device; - unsigned long base; - unsigned char irq; - - while ((pci_dev = pci_get_device - (DT3155_VENDORID, DT3155_DEVICEID, pci_dev)) != NULL) - { - pci_index ++; - - /* Is it really there? */ - if ((error = - pci_read_config_word(pci_dev, PCI_CLASS_DEVICE, &rev_device))) - continue; - - /* Found a board */ - DT_3155_DEBUG_MSG("DT3155: Device number %d \n", pci_index); - - /* Make sure the driver was compiled with enough buffers to handle - this many boards */ - if (pci_index > MAXBOARDS) { - printk("DT3155: ERROR - found %d devices, but driver only configured " - "for %d devices\n" - "DT3155: Please change MAXBOARDS in dt3155.h\n", - pci_index, MAXBOARDS); - goto err; - } - - /* Now, just go out and make sure that this/these device(s) is/are - actually mapped into the kernel address space */ - if ((error = pci_read_config_dword(pci_dev, PCI_BASE_ADDRESS_0, - (u32 *) &base))) - { - printk("DT3155: Was not able to find device \n"); - goto err; - } - - DT_3155_DEBUG_MSG("DT3155: Base address 0 for device is %lx \n", base); - dt3155_status[pci_index-1].reg_addr = base; - - /* Remap the base address to a logical address through which we - * can access it. */ - dt3155_lbase[pci_index - 1] = ioremap(base,PCI_PAGE_SIZE); - dt3155_status[pci_index - 1].reg_addr = base; - DT_3155_DEBUG_MSG("DT3155: New logical address is %p \n", - dt3155_lbase[pci_index-1]); - if (!dt3155_lbase[pci_index-1]) - { - printk("DT3155: Unable to remap control registers\n"); - goto err; - } - - if ((error = pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &irq))) - { - printk("DT3155: Was not able to find device \n"); - goto err; - } - - DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq); - dt3155_status[pci_index-1].irq = irq; - /* Set flag: kth device found! */ - dt3155_status[pci_index-1].device_installed = 1; - printk("DT3155: Installing device %d w/irq %d and address %p\n", - pci_index, - dt3155_status[pci_index-1].irq, - dt3155_lbase[pci_index-1]); - - } - ndevices = pci_index; - - return DT_3155_SUCCESS; - -err: - pci_dev_put(pci_dev); - return DT_3155_FAILURE; -} - -u32 allocatorAddr = 0; - -/***************************************************** - * init_module() - *****************************************************/ -int init_module(void) -{ - int index; - int rcode = 0; - char *devname[MAXBOARDS]; - - devname[0] = "dt3155a"; -#if MAXBOARDS == 2 - devname[1] = "dt3155b"; -#endif - - printk("DT3155: Loading module...\n"); - - /* Register the device driver */ - rcode = register_chrdev(dt3155_major, "dt3155", &dt3155_fops); - if(rcode < 0) - { - printk(KERN_INFO "DT3155: register_chrdev failed \n"); - return rcode; - } - - if(dt3155_major == 0) - dt3155_major = rcode; /* dynamic */ - - - /* init the status variables. */ - /* DMA memory is taken care of in setup_buffers() */ - for (index = 0; index < MAXBOARDS; index++) - { - dt3155_status[index].config.acq_mode = DT3155_MODE_FRAME; - dt3155_status[index].config.continuous = DT3155_ACQ; - dt3155_status[index].config.cols = DT3155_MAX_COLS; - dt3155_status[index].config.rows = DT3155_MAX_ROWS; - dt3155_status[index].state = DT3155_STATE_IDLE; - - /* find_PCI() will check if devices are installed; */ - /* first assume they're not: */ - dt3155_status[index].mem_addr = 0; - dt3155_status[index].mem_size = 0; - dt3155_status[index].state = DT3155_STATE_IDLE; - dt3155_status[index].device_installed = 0; - } - - /* Now let's find the hardware. find_PCI() will set ndevices to the - * number of cards found in this machine. */ - { - if ((rcode = find_PCI()) != DT_3155_SUCCESS) - { - printk("DT3155 error: find_PCI() failed to find dt3155 board(s)\n"); - unregister_chrdev(dt3155_major, "dt3155"); - return rcode; - } - } - - /* Ok, time to setup the frame buffers */ - if((rcode = dt3155_setup_buffers(&allocatorAddr)) < 0) - { - printk("DT3155: Error: setting up buffer not large enough."); - unregister_chrdev(dt3155_major, "dt3155"); - return rcode; - } - - /* If we are this far, then there is enough RAM */ - /* for the buffers: Print the configuration. */ - for( index = 0; index < ndevices; index++) - { - printk("DT3155: Device = %d; acq_mode = %d; " - "continuous = %d; cols = %d; rows = %d;\n", - index , - dt3155_status[index].config.acq_mode, - dt3155_status[index].config.continuous, - dt3155_status[index].config.cols, - dt3155_status[index].config.rows); - printk("DT3155: m_addr = 0x%x; m_size = %ld; " - "state = %d; device_installed = %d\n", - dt3155_status[index].mem_addr, - (long int)dt3155_status[index].mem_size, - dt3155_status[index].state, - dt3155_status[index].device_installed); - } - - /* Disable ALL interrupts */ - int_csr_r.reg = 0; - for( index = 0; index < ndevices; index++) - { - WriteMReg((dt3155_lbase[index] + INT_CSR), int_csr_r.reg); - if(dt3155_status[index].device_installed) - { - /* - * This driver *looks* like it can handle sharing interrupts, - * but I can't actually test myself. I've had reports that it - * DOES work so I'll enable it for now. This comment will remain - * as a reminder in case any problems arise. (SS) - */ - /* in older kernels flags are: SA_SHIRQ | SA_INTERRUPT */ - rcode = request_irq(dt3155_status[index].irq, (void *)dt3155_isr, - IRQF_SHARED | IRQF_DISABLED, devname[index], - (void*) &dt3155_status[index]); - if(rcode < 0) - { - printk("DT3155: minor %d request_irq failed for IRQ %d\n", - index, dt3155_status[index].irq); - unregister_chrdev(dt3155_major, "dt3155"); - return rcode; - } - } - } - - printk("DT3155: finished loading\n"); - - return 0; -} - -/***************************************************** - * cleanup_module(void) - * - *****************************************************/ -void cleanup_module(void) -{ - int index; - - printk("DT3155: cleanup_module called\n"); - - /* removed DMA allocated with the allocator */ -#ifdef STANDALONE_ALLOCATOR - if (allocatorAddr != 0) - allocator_free_dma(allocatorAddr); -#else - allocator_cleanup(); -#endif - - unregister_chrdev(dt3155_major, "dt3155"); - - for(index = 0; index < ndevices; index++) - { - if(dt3155_status[index].device_installed == 1) - { - printk("DT3155: Freeing irq %d for device %d\n", - dt3155_status[index].irq, index); - free_irq(dt3155_status[index].irq, (void*)&dt3155_status[index]); - } - } -} - diff --git a/drivers/staging/dt3155/dt3155_drv.h b/drivers/staging/dt3155/dt3155_drv.h deleted file mode 100644 index 95e68c3388a4..000000000000 --- a/drivers/staging/dt3155/dt3155_drv.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - -Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, - Scott Smedley - -This file is part of the DT3155 Device Driver. - -The DT3155 Device Driver is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The DT3155 Device Driver is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty -of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the DT3155 Device Driver; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307 USA -*/ - -#ifndef DT3155_DRV_INC -#define DT3155_DRV_INC - -/* kernel logical address of the frame grabbers */ -extern u8 *dt3155_lbase[MAXBOARDS]; - -/* kernel logical address of ram buffer */ -extern u8 *dt3155_bbase; - -#ifdef __KERNEL__ -#include <linux/wait.h> - -/* wait queue for reads */ -extern wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS]; -#endif - -/* number of devices */ -extern u32 ndevices; - -extern int dt3155_errno; - -#endif diff --git a/drivers/staging/dt3155/dt3155_io.c b/drivers/staging/dt3155/dt3155_io.c deleted file mode 100644 index 7792e712d16e..000000000000 --- a/drivers/staging/dt3155/dt3155_io.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, - * Jason Lapenta, Scott Smedley - * - * This file is part of the DT3155 Device Driver. - * - * The DT3155 Device Driver is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * The DT3155 Device Driver is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - */ - -/* - * This file provides some basic register io routines. It is modified from - * demo code provided by Data Translations. - */ - -#include <linux/delay.h> -#include "dt3155.h" -#include "dt3155_io.h" -#include "dt3155_drv.h" - - -/****** local copies of board's 32 bit registers ******/ -u32 even_dma_start_r; /* bit 0 should always be 0 */ -u32 odd_dma_start_r; /* .. */ -u32 even_dma_stride_r; /* bits 0&1 should always be 0 */ -u32 odd_dma_stride_r; /* .. */ -u32 even_pixel_fmt_r; -u32 odd_pixel_fmt_r; - -FIFO_TRIGGER_R fifo_trigger_r; -XFER_MODE_R xfer_mode_r; -CSR1_R csr1_r; -RETRY_WAIT_CNT_R retry_wait_cnt_r; -INT_CSR_R int_csr_r; - -u32 even_fld_mask_r; -u32 odd_fld_mask_r; - -MASK_LENGTH_R mask_length_r; -FIFO_FLAG_CNT_R fifo_flag_cnt_r; -IIC_CLK_DUR_R iic_clk_dur_r; -IIC_CSR1_R iic_csr1_r; -IIC_CSR2_R iic_csr2_r; -DMA_UPPER_LMT_R even_dma_upper_lmt_r; -DMA_UPPER_LMT_R odd_dma_upper_lmt_r; - - - -/******** local copies of board's 8 bit I2C registers ******/ -I2C_CSR2 i2c_csr2; -I2C_EVEN_CSR i2c_even_csr; -I2C_ODD_CSR i2c_odd_csr; -I2C_CONFIG i2c_config; -u8 i2c_dt_id; -u8 i2c_x_clip_start; -u8 i2c_y_clip_start; -u8 i2c_x_clip_end; -u8 i2c_y_clip_end; -u8 i2c_ad_addr; -u8 i2c_ad_lut; -I2C_AD_CMD i2c_ad_cmd; -u8 i2c_dig_out; -u8 i2c_pm_lut_addr; -u8 i2c_pm_lut_data; - -/* - * wait_ibsyclr() - * - * This function handles read/write timing and r/w timeout error - */ -static int wait_ibsyclr(u8 *lpReg) -{ - /* wait 100 microseconds */ - udelay(100L); - /* __delay(loops_per_sec/10000); */ - - ReadMReg(lpReg + IIC_CSR2, iic_csr2_r.reg); - if (iic_csr2_r.fld.NEW_CYCLE) { - /* if NEW_CYCLE didn't clear */ - /* TIMEOUT ERROR */ - dt3155_errno = DT_ERR_I2C_TIMEOUT; - return -ETIMEDOUT; - } - - return 0; /* no error */ -} - -/* - * WriteI2C() - * - * This function handles writing to 8-bit DT3155 registers - * - * 1st parameter is pointer to 32-bit register base address - * 2nd parameter is reg. index; - * 3rd is value to be written - */ -int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal) -{ - /* read 32 bit IIC_CSR2 register data into union */ - - ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg); - - /* for write operation */ - iic_csr2_r.fld.DIR_RD = 0; - /* I2C address of I2C register: */ - iic_csr2_r.fld.DIR_ADDR = wIregIndex; - /* 8 bit data to be written to I2C reg */ - iic_csr2_r.fld.DIR_WR_DATA = byVal; - /* will start a direct I2C cycle: */ - iic_csr2_r.fld.NEW_CYCLE = 1; - - /* xfer union data into 32 bit IIC_CSR2 register */ - WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg); - - /* wait for IIC cycle to finish */ - return wait_ibsyclr(lpReg); -} - -/* - * ReadI2C() - * - * This function handles reading from 8-bit DT3155 registers - * - * 1st parameter is pointer to 32-bit register base address - * 2nd parameter is reg. index; - * 3rd is adrs of value to be read - */ -int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal) -{ - int writestat; /* status for return */ - - /* read 32 bit IIC_CSR2 register data into union */ - ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg); - - /* for read operation */ - iic_csr2_r.fld.DIR_RD = 1; - - /* I2C address of I2C register: */ - iic_csr2_r.fld.DIR_ADDR = wIregIndex; - - /* will start a direct I2C cycle: */ - iic_csr2_r.fld.NEW_CYCLE = 1; - - /* xfer union's data into 32 bit IIC_CSR2 register */ - WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg); - - /* wait for IIC cycle to finish */ - writestat = wait_ibsyclr(lpReg); - - /* Next 2 commands read 32 bit IIC_CSR1 register's data into union */ - /* first read data is in IIC_CSR1 */ - ReadMReg((lpReg + IIC_CSR1), iic_csr1_r.reg); - - /* now get data u8 out of register */ - *byVal = (u8) iic_csr1_r.fld.RD_DATA; - - return writestat; -} diff --git a/drivers/staging/dt3155/dt3155_io.h b/drivers/staging/dt3155/dt3155_io.h deleted file mode 100644 index d1a25100169f..000000000000 --- a/drivers/staging/dt3155/dt3155_io.h +++ /dev/null @@ -1,358 +0,0 @@ -/* - -Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, - Jason Lapenta, Scott Smedley - -This file is part of the DT3155 Device Driver. - -The DT3155 Device Driver is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The DT3155 Device Driver is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty -of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the DT3155 Device Driver; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307 USA - - --- Changes -- - - Date Programmer Description of changes made - ------------------------------------------------------------------- - 24-Jul-2002 SS GPL licence. - -*/ - -/* This code is a modified version of examples provided by Data Translations.*/ - -#ifndef DT3155_IO_INC -#define DT3155_IO_INC - -/* macros to access registers */ - -#define WriteMReg(Address, Data) (*((u32 *)(Address)) = Data) -#define ReadMReg(Address, Data) (Data = *((u32 *)(Address))) - -/***************** 32 bit register globals **************/ - -/* offsets for 32-bit memory mapped registers */ - -#define EVEN_DMA_START 0x000 -#define ODD_DMA_START 0x00C -#define EVEN_DMA_STRIDE 0x018 -#define ODD_DMA_STRIDE 0x024 -#define EVEN_PIXEL_FMT 0x030 -#define ODD_PIXEL_FMT 0x034 -#define FIFO_TRIGGER 0x038 -#define XFER_MODE 0x03C -#define CSR1 0x040 -#define RETRY_WAIT_CNT 0x044 -#define INT_CSR 0x048 -#define EVEN_FLD_MASK 0x04C -#define ODD_FLD_MASK 0x050 -#define MASK_LENGTH 0x054 -#define FIFO_FLAG_CNT 0x058 -#define IIC_CLK_DUR 0x05C -#define IIC_CSR1 0x060 -#define IIC_CSR2 0x064 -#define EVEN_DMA_UPPR_LMT 0x08C -#define ODD_DMA_UPPR_LMT 0x090 - -#define CLK_DUR_VAL 0x01010101 - - - -/******** Assignments and Typedefs for 32 bit Memory Mapped Registers ********/ - -typedef union fifo_trigger_tag { - u32 reg; - struct { - u32 PACKED:6; - u32 :9; - u32 PLANER:7; - u32 :9; - } fld; -} FIFO_TRIGGER_R; - -typedef union xfer_mode_tag { - u32 reg; - struct { - u32 :2; - u32 FIELD_TOGGLE:1; - u32 :5; - u32 :2; - u32 :22; - } fld; -} XFER_MODE_R; - -typedef union csr1_tag { - u32 reg; - struct { - u32 CAP_CONT_EVE:1; - u32 CAP_CONT_ODD:1; - u32 CAP_SNGL_EVE:1; - u32 CAP_SNGL_ODD:1; - u32 FLD_DN_EVE :1; - u32 FLD_DN_ODD :1; - u32 SRST :1; - u32 FIFO_EN :1; - u32 FLD_CRPT_EVE:1; - u32 FLD_CRPT_ODD:1; - u32 ADDR_ERR_EVE:1; - u32 ADDR_ERR_ODD:1; - u32 CRPT_DIS :1; - u32 RANGE_EN :1; - u32 :16; - } fld; -} CSR1_R; - -typedef union retry_wait_cnt_tag { - u32 reg; - struct { - u32 RTRY_WAIT_CNT:8; - u32 :24; - } fld; -} RETRY_WAIT_CNT_R; - -typedef union int_csr_tag { - u32 reg; - struct { - u32 FLD_END_EVE :1; - u32 FLD_END_ODD :1; - u32 FLD_START :1; - u32 :5; - u32 FLD_END_EVE_EN:1; - u32 FLD_END_ODD_EN:1; - u32 FLD_START_EN :1; - u32 :21; - } fld; -} INT_CSR_R; - -typedef union mask_length_tag { - u32 reg; - struct { - u32 MASK_LEN_EVE:5; - u32 :11; - u32 MASK_LEN_ODD:5; - u32 :11; - } fld; -} MASK_LENGTH_R; - -typedef union fifo_flag_cnt_tag { - u32 reg; - struct { - u32 AF_COUNT:7; - u32 :9; - u32 AE_COUNT:7; - u32 :9; - } fld; -} FIFO_FLAG_CNT_R; - -typedef union iic_clk_dur { - u32 reg; - struct { - u32 PHASE_1:8; - u32 PHASE_2:8; - u32 PHASE_3:8; - u32 PHASE_4:8; - } fld; -} IIC_CLK_DUR_R; - -typedef union iic_csr1_tag { - u32 reg; - struct { - u32 AUTO_EN :1; - u32 BYPASS :1; - u32 SDA_OUT :1; - u32 SCL_OUT :1; - u32 :4; - u32 AUTO_ABORT :1; - u32 DIRECT_ABORT:1; - u32 SDA_IN :1; - u32 SCL_IN :1; - u32 :4; - u32 AUTO_ADDR :8; - u32 RD_DATA :8; - } fld; -} IIC_CSR1_R; - -/********************************** - * iic_csr2_tag - */ -typedef union iic_csr2_tag { - u32 reg; - struct { - u32 DIR_WR_DATA :8; - u32 DIR_SUB_ADDR:8; - u32 DIR_RD :1; - u32 DIR_ADDR :7; - u32 NEW_CYCLE :1; - u32 :7; - } fld; -} IIC_CSR2_R; - -/* use for both EVEN and ODD DMA UPPER LIMITS */ - -/* - * dma_upper_lmt_tag - */ -typedef union dma_upper_lmt_tag { - u32 reg; - struct { - u32 DMA_UPPER_LMT_VAL:24; - u32 :8; - } fld; -} DMA_UPPER_LMT_R; - - -/* - * Global declarations of local copies of boards' 32 bit registers - */ -extern u32 even_dma_start_r; /* bit 0 should always be 0 */ -extern u32 odd_dma_start_r; /* .. */ -extern u32 even_dma_stride_r; /* bits 0&1 should always be 0 */ -extern u32 odd_dma_stride_r; /* .. */ -extern u32 even_pixel_fmt_r; -extern u32 odd_pixel_fmt_r; - -extern FIFO_TRIGGER_R fifo_trigger_r; -extern XFER_MODE_R xfer_mode_r; -extern CSR1_R csr1_r; -extern RETRY_WAIT_CNT_R retry_wait_cnt_r; -extern INT_CSR_R int_csr_r; - -extern u32 even_fld_mask_r; -extern u32 odd_fld_mask_r; - -extern MASK_LENGTH_R mask_length_r; -extern FIFO_FLAG_CNT_R fifo_flag_cnt_r; -extern IIC_CLK_DUR_R iic_clk_dur_r; -extern IIC_CSR1_R iic_csr1_r; -extern IIC_CSR2_R iic_csr2_r; -extern DMA_UPPER_LMT_R even_dma_upper_lmt_r; -extern DMA_UPPER_LMT_R odd_dma_upper_lmt_r; - - - -/***************** 8 bit I2C register globals ***********/ -#define CSR2 0x010 /* indices of 8-bit I2C mapped reg's*/ -#define EVEN_CSR 0x011 -#define ODD_CSR 0x012 -#define CONFIG 0x013 -#define DT_ID 0x01F -#define X_CLIP_START 0x020 -#define Y_CLIP_START 0x022 -#define X_CLIP_END 0x024 -#define Y_CLIP_END 0x026 -#define AD_ADDR 0x030 -#define AD_LUT 0x031 -#define AD_CMD 0x032 -#define DIG_OUT 0x040 -#define PM_LUT_ADDR 0x050 -#define PM_LUT_DATA 0x051 - - -/******** Assignments and Typedefs for 8 bit I2C Registers********************/ - -typedef union i2c_csr2_tag { - u8 reg; - struct { - u8 CHROM_FIL:1; - u8 SYNC_SNTL:1; - u8 HZ50:1; - u8 SYNC_PRESENT:1; - u8 BUSY_EVE:1; - u8 BUSY_ODD:1; - u8 DISP_PASS:1; - } fld; -} I2C_CSR2; - -typedef union i2c_even_csr_tag { - u8 reg; - struct { - u8 DONE_EVE :1; - u8 SNGL_EVE :1; - u8 ERROR_EVE:1; - u8 :5; - } fld; -} I2C_EVEN_CSR; - -typedef union i2c_odd_csr_tag { - u8 reg; - struct { - u8 DONE_ODD:1; - u8 SNGL_ODD:1; - u8 ERROR_ODD:1; - u8 :5; - } fld; -} I2C_ODD_CSR; - -typedef union i2c_config_tag { - u8 reg; - struct { - u8 ACQ_MODE:2; - u8 EXT_TRIG_EN:1; - u8 EXT_TRIG_POL:1; - u8 H_SCALE:1; - u8 CLIP:1; - u8 PM_LUT_SEL:1; - u8 PM_LUT_PGM:1; - } fld; -} I2C_CONFIG; - - -typedef union i2c_ad_cmd_tag { - /* bits can have 3 different meanings depending on value of AD_ADDR */ - u8 reg; - /* Bt252 Command Register if AD_ADDR = 00h */ - struct { - u8 :2; - u8 SYNC_LVL_SEL:2; - u8 SYNC_CNL_SEL:2; - u8 DIGITIZE_CNL_SEL1:2; - } bt252_command; - - /* Bt252 IOUT0 register if AD_ADDR = 01h */ - struct { - u8 IOUT_DATA:8; - } bt252_iout0; - - /* BT252 IOUT1 register if AD_ADDR = 02h */ - struct { - u8 IOUT_DATA:8; - } bt252_iout1; -} I2C_AD_CMD; - - -/***** Global declarations of local copies of boards' 8 bit I2C registers ***/ - -extern I2C_CSR2 i2c_csr2; -extern I2C_EVEN_CSR i2c_even_csr; -extern I2C_ODD_CSR i2c_odd_csr; -extern I2C_CONFIG i2c_config; -extern u8 i2c_dt_id; -extern u8 i2c_x_clip_start; -extern u8 i2c_y_clip_start; -extern u8 i2c_x_clip_end; -extern u8 i2c_y_clip_end; -extern u8 i2c_ad_addr; -extern u8 i2c_ad_lut; -extern I2C_AD_CMD i2c_ad_cmd; -extern u8 i2c_dig_out; -extern u8 i2c_pm_lut_addr; -extern u8 i2c_pm_lut_data; - -/* Functions for Global use */ - -/* access 8-bit IIC registers */ - -extern int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal); -extern int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal); - -#endif diff --git a/drivers/staging/dt3155/dt3155_isr.c b/drivers/staging/dt3155/dt3155_isr.c deleted file mode 100644 index 33ddc9c057ff..000000000000 --- a/drivers/staging/dt3155/dt3155_isr.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - -Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, - Jason Lapenta, Scott Smedley, Greg Sharp - -This file is part of the DT3155 Device Driver. - -The DT3155 Device Driver is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The DT3155 Device Driver is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty -of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the DT3155 Device Driver; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307 USA - - File: dt3155_isr.c -Purpose: Buffer management routines, and other routines for the ISR - (the actual isr is in dt3155_drv.c) - --- Changes -- - - Date Programmer Description of changes made - ------------------------------------------------------------------- - 03-Jul-2000 JML n/a - 02-Apr-2002 SS Mods to make work with separate allocator - module; Merged John Roll's mods to make work with - multiple boards. - 10-Jul-2002 GCS Complete rewrite of setup_buffers to disallow - buffers which span a 4MB boundary. - 24-Jul-2002 SS GPL licence. - 30-Jul-2002 NJC Added support for buffer loop. - 31-Jul-2002 NJC Complete rewrite of buffer management - 02-Aug-2002 NJC Including slab.h instead of malloc.h (no warning). - Also, allocator_init() now returns allocator_max - so cleaned up allocate_buffers() accordingly. - 08-Aug-2005 SS port to 2.6 kernel. - -*/ - -#include <asm/system.h> -#include <linux/gfp.h> -#include <linux/sched.h> -#include <linux/types.h> - -#include "dt3155.h" -#include "dt3155_drv.h" -#include "dt3155_io.h" -#include "dt3155_isr.h" -#include "allocator.h" - -#define FOUR_MB (0x0400000) /* Can't DMA accross a 4MB boundary!*/ -#define UPPER_10_BITS (0x3FF<<22) /* Can't DMA accross a 4MB boundary!*/ - - -/* Pointer into global structure for handling buffers */ -struct dt3155_fbuffer *dt3155_fbuffer[MAXBOARDS] = {NULL -#if MAXBOARDS == 2 - , NULL -#endif -}; - -/****************************************************************************** - * Simple array based que struct - * - * Some handy functions using the buffering structure. - *****************************************************************************/ - - -/*************************** - * are_empty_buffers - * m is minor # of device - ***************************/ -bool are_empty_buffers(int m) -{ - return dt3155_fbuffer[m]->empty_len; -} - -/************************** - * push_empty - * m is minor # of device - * - * This is slightly confusing. The number empty_len is the literal # - * of empty buffers. After calling, empty_len-1 is the index into the - * empty buffer stack. So, if empty_len == 1, there is one empty buffer, - * given by dt3155_fbuffer[m]->empty_buffers[0]. - * empty_buffers should never fill up, though this is not checked. - **************************/ -void push_empty(int index, int m) -{ - dt3155_fbuffer[m]->empty_buffers[dt3155_fbuffer[m]->empty_len] = index; - dt3155_fbuffer[m]->empty_len++; -} - -/************************** - * pop_empty(m) - * m is minor # of device - **************************/ -int pop_empty(int m) -{ - dt3155_fbuffer[m]->empty_len--; - return dt3155_fbuffer[m]->empty_buffers[dt3155_fbuffer[m]->empty_len]; -} - -/************************* - * is_ready_buf_empty(m) - * m is minor # of device - *************************/ -bool is_ready_buf_empty(int m) -{ - return ((dt3155_fbuffer[m]->ready_len) == 0); -} - -/************************* - * is_ready_buf_full(m) - * m is minor # of device - * this should *never* be true if there are any active, locked or empty - * buffers, since it corresponds to nbuffers ready buffers!! - * 7/31/02: total rewrite. --NJC - *************************/ -bool is_ready_buf_full(int m) -{ - return dt3155_fbuffer[m]->ready_len == dt3155_fbuffer[m]->nbuffers; -} - -/***************************************************** - * push_ready(m, buffer) - * m is minor # of device - * - *****************************************************/ -void push_ready(int m, int index) -{ - int head = dt3155_fbuffer[m]->ready_head; - - dt3155_fbuffer[m]->ready_que[head] = index; - dt3155_fbuffer[m]->ready_head = ((head + 1) % - (dt3155_fbuffer[m]->nbuffers)); - dt3155_fbuffer[m]->ready_len++; - -} - -/***************************************************** - * get_tail() - * m is minor # of device - * - * Simply comptutes the tail given the head and the length. - *****************************************************/ -static int get_tail(int m) -{ - return (dt3155_fbuffer[m]->ready_head - - dt3155_fbuffer[m]->ready_len + - dt3155_fbuffer[m]->nbuffers)% - (dt3155_fbuffer[m]->nbuffers); -} - - - -/***************************************************** - * pop_ready() - * m is minor # of device - * - * This assumes that there is a ready buffer ready... should - * be checked (e.g. with is_ready_buf_empty() prior to call. - *****************************************************/ -int pop_ready(int m) -{ - int tail; - tail = get_tail(m); - dt3155_fbuffer[m]->ready_len--; - return dt3155_fbuffer[m]->ready_que[tail]; -} - - -/***************************************************** - * printques - * m is minor # of device - *****************************************************/ -void printques(int m) -{ - int head = dt3155_fbuffer[m]->ready_head; - int tail; - int num = dt3155_fbuffer[m]->nbuffers; - int frame_index; - int index; - - tail = get_tail(m); - - printk("\n R:"); - for (index = tail; index != head; index++, index = index % (num)) { - frame_index = dt3155_fbuffer[m]->ready_que[index]; - printk(" %d ", frame_index); - } - - printk("\n E:"); - for (index = 0; index < dt3155_fbuffer[m]->empty_len; index++) { - frame_index = dt3155_fbuffer[m]->empty_buffers[index]; - printk(" %d ", frame_index); - } - - frame_index = dt3155_fbuffer[m]->active_buf; - printk("\n A: %d", frame_index); - - frame_index = dt3155_fbuffer[m]->locked_buf; - printk("\n L: %d\n", frame_index); - -} - -/***************************************************** - * adjust_4MB - * - * If a buffer intersects the 4MB boundary, push - * the start address up to the beginning of the - * next 4MB chunk (assuming bufsize < 4MB). - *****************************************************/ -u32 adjust_4MB(u32 buf_addr, u32 bufsize) -{ - if (((buf_addr+bufsize) & UPPER_10_BITS) != (buf_addr & UPPER_10_BITS)) - return (buf_addr+bufsize) & UPPER_10_BITS; - else - return buf_addr; -} - - -/***************************************************** - * allocate_buffers - * - * Try to allocate enough memory for all requested - * buffers. If there is not enough free space - * try for less memory. - *****************************************************/ -void allocate_buffers(u32 *buf_addr, u32* total_size_kbs, - u32 bufsize) -{ - /* Compute the minimum amount of memory guaranteed to hold all - MAXBUFFERS such that no buffer crosses the 4MB boundary. - Store this value in the variable "full_size" */ - - u32 allocator_max; - u32 bufs_per_chunk = (FOUR_MB / bufsize); - u32 filled_chunks = (MAXBUFFERS-1) / bufs_per_chunk; - u32 leftover_bufs = MAXBUFFERS - filled_chunks * bufs_per_chunk; - - u32 full_size = bufsize /* possibly unusable part of 1st chunk */ - + filled_chunks * FOUR_MB /* max # of completely filled 4mb chunks */ - + leftover_bufs * bufsize; /* these buffs will be in a partly filled - chunk at beginning or end */ - - u32 full_size_kbs = 1 + (full_size-1) / 1024; - u32 min_size_kbs = 2*ndevices*bufsize / 1024; - u32 size_kbs; - - /* Now, try to allocate full_size. If this fails, keep trying for - less & less memory until it succeeds. */ -#ifndef STANDALONE_ALLOCATOR - /* initialize the allocator */ - allocator_init(&allocator_max); -#endif - size_kbs = full_size_kbs; - *buf_addr = 0; - printk("DT3155: We would like to get: %d KB\n", full_size_kbs); - printk("DT3155: ...but need at least: %d KB\n", min_size_kbs); - printk("DT3155: ...the allocator has: %d KB\n", allocator_max); - size_kbs = (full_size_kbs <= allocator_max ? full_size_kbs : allocator_max); - if (size_kbs > min_size_kbs) { - if ((*buf_addr = allocator_allocate_dma(size_kbs, GFP_KERNEL)) != 0) { - printk("DT3155: Managed to allocate: %d KB\n", size_kbs); - *total_size_kbs = size_kbs; - return; - } - } - /* If we got here, the allocation failed */ - printk("DT3155: Allocator failed!\n"); - *buf_addr = 0; - *total_size_kbs = 0; - return; - -} - - -/***************************************************** - * dt3155_setup_buffers - * - * setup_buffers just puts the buffering system into - * a consistent state before the start of interrupts - * - * JML : it looks like all the buffers need to be - * continuous. So I'm going to try and allocate one - * continuous buffer. - * - * GCS : Fix DMA problems when buffer spans - * 4MB boundary. Also, add error checking. This - * function will return -ENOMEM when not enough memory. - *****************************************************/ -u32 dt3155_setup_buffers(u32 *allocatorAddr) - -{ - u32 index; - u32 rambuff_addr; /* start of allocation */ - u32 rambuff_size; /* total size allocated to driver */ - u32 rambuff_acm; /* accumlator, keep track of how much - is left after being split up*/ - u32 rambuff_end; /* end of rambuff */ - u32 numbufs; /* number of useful buffers allocated (per device) */ - u32 bufsize = DT3155_MAX_ROWS * DT3155_MAX_COLS; - int m; /* minor # of device, looped for all devs */ - - /* zero the fbuffer status and address structure */ - for (m = 0; m < ndevices; m++) { - dt3155_fbuffer[m] = &(dt3155_status[m].fbuffer); - - /* Make sure the buffering variables are consistent */ - { - u8 *ptr = (u8 *) dt3155_fbuffer[m]; - for (index = 0; index < sizeof(struct dt3155_fbuffer); index++) - *(ptr++) = 0; - } - } - - /* allocate a large contiguous chunk of RAM */ - allocate_buffers(&rambuff_addr, &rambuff_size, bufsize); - printk("DT3155: mem info\n"); - printk(" - rambuf_addr = 0x%x\n", rambuff_addr); - printk(" - length (kb) = %u\n", rambuff_size); - if (rambuff_addr == 0) { - printk(KERN_INFO - "DT3155: Error setup_buffers() allocator dma failed\n"); - return -ENOMEM; - } - *allocatorAddr = rambuff_addr; - rambuff_end = rambuff_addr + 1024 * rambuff_size; - - /* after allocation, we need to count how many useful buffers there - are so we can give an equal number to each device */ - rambuff_acm = rambuff_addr; - for (index = 0; index < MAXBUFFERS; index++) { - rambuff_acm = adjust_4MB(rambuff_acm, bufsize);/*avoid spanning 4MB bdry*/ - if (rambuff_acm + bufsize > rambuff_end) - break; - rambuff_acm += bufsize; - } - /* Following line is OK, will waste buffers if index - * not evenly divisible by ndevices -NJC*/ - numbufs = index / ndevices; - printk(" - numbufs = %u\n", numbufs); - if (numbufs < 2) { - printk(KERN_INFO - "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n"); - return -ENOMEM; - } - - /* now that we have board memory we spit it up */ - /* between the boards and the buffers */ - rambuff_acm = rambuff_addr; - for (m = 0; m < ndevices; m++) { - rambuff_acm = adjust_4MB(rambuff_acm, bufsize); - - /* Save the start of this boards buffer space (for mmap). */ - dt3155_status[m].mem_addr = rambuff_acm; - - for (index = 0; index < numbufs; index++) { - rambuff_acm = adjust_4MB(rambuff_acm, bufsize); - if (rambuff_acm + bufsize > rambuff_end) { - /* Should never happen */ - printk("DT3155 PROGRAM ERROR (GCS)\n" - "Error distributing allocated buffers\n"); - return -ENOMEM; - } - - dt3155_fbuffer[m]->frame_info[index].addr = rambuff_acm; - push_empty(index, m); - /* printk(" - Buffer : %lx\n", - * dt3155_fbuffer[m]->frame_info[index].addr); - */ - dt3155_fbuffer[m]->nbuffers += 1; - rambuff_acm += bufsize; - } - - /* Make sure there is an active buffer there. */ - dt3155_fbuffer[m]->active_buf = pop_empty(m); - dt3155_fbuffer[m]->even_happened = 0; - dt3155_fbuffer[m]->even_stopped = 0; - - /* make sure there is no locked_buf JML 2/28/00 */ - dt3155_fbuffer[m]->locked_buf = -1; - - dt3155_status[m].mem_size = - rambuff_acm - dt3155_status[m].mem_addr; - - /* setup the ready queue */ - dt3155_fbuffer[m]->ready_head = 0; - dt3155_fbuffer[m]->ready_len = 0; - printk("Available buffers for device %d: %d\n", - m, dt3155_fbuffer[m]->nbuffers); - } - - return 1; -} - -/***************************************************** - * internal_release_locked_buffer - * - * The internal function for releasing a locked buffer. - * It assumes interrupts are turned off. - * - * m is minor number of device - *****************************************************/ -static void internal_release_locked_buffer(int m) -{ - /* Pointer into global structure for handling buffers */ - if (dt3155_fbuffer[m]->locked_buf >= 0) { - push_empty(dt3155_fbuffer[m]->locked_buf, m); - dt3155_fbuffer[m]->locked_buf = -1; - } -} - - -/***************************************************** - * dt3155_release_locked_buffer() - * m is minor # of device - * - * The user function of the above. - * - *****************************************************/ -void dt3155_release_locked_buffer(int m) -{ - unsigned long int flags; - local_save_flags(flags); - local_irq_disable(); - internal_release_locked_buffer(m); - local_irq_restore(flags); -} - - -/***************************************************** - * dt3155_flush() - * m is minor # of device - * - *****************************************************/ -int dt3155_flush(int m) -{ - int index; - unsigned long int flags; - local_save_flags(flags); - local_irq_disable(); - - internal_release_locked_buffer(m); - dt3155_fbuffer[m]->empty_len = 0; - - for (index = 0; index < dt3155_fbuffer[m]->nbuffers; index++) - push_empty(index, m); - - /* Make sure there is an active buffer there. */ - dt3155_fbuffer[m]->active_buf = pop_empty(m); - - dt3155_fbuffer[m]->even_happened = 0; - dt3155_fbuffer[m]->even_stopped = 0; - - /* setup the ready queue */ - dt3155_fbuffer[m]->ready_head = 0; - dt3155_fbuffer[m]->ready_len = 0; - - local_irq_restore(flags); - - return 0; -} - -/***************************************************** - * dt3155_get_ready_buffer() - * m is minor # of device - * - * get_ready_buffer will grab the next chunk of data - * if it is already there, otherwise it returns 0. - * If the user has a buffer locked it will unlock - * that buffer before returning the new one. - *****************************************************/ -int dt3155_get_ready_buffer(int m) -{ - int frame_index; - unsigned long int flags; - local_save_flags(flags); - local_irq_disable(); - -#ifdef DEBUG_QUES_A - printques(m); -#endif - - internal_release_locked_buffer(m); - - if (is_ready_buf_empty(m)) - frame_index = -1; - else { - frame_index = pop_ready(m); - dt3155_fbuffer[m]->locked_buf = frame_index; - } - -#ifdef DEBUG_QUES_B - printques(m); -#endif - - local_irq_restore(flags); - - return frame_index; -} diff --git a/drivers/staging/dt3155/dt3155_isr.h b/drivers/staging/dt3155/dt3155_isr.h deleted file mode 100644 index 7d474cf743d8..000000000000 --- a/drivers/staging/dt3155/dt3155_isr.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - -Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, - Jason Lapenta, Scott Smedley - -This file is part of the DT3155 Device Driver. - -The DT3155 Device Driver is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The DT3155 Device Driver is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty -of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the DT3155 Device Driver; if not, write to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -MA 02111-1307 USA - - --- Changes -- - - Date Programmer Description of changes made - ------------------------------------------------------------------- - 03-Jul-2000 JML n/a - 24-Jul-2002 SS GPL licence. - 26-Oct-2009 SS Porting to 2.6.30 kernel. - --- notes -- - -*/ - -#ifndef DT3155_ISR_H -#define DT3155_ISR_H - -extern struct dt3155_fbuffer *dt3155_fbuffer[MAXBOARDS]; - -/* User functions for buffering */ -/* Initialize the buffering system. This should */ -/* be called prior to enabling interrupts */ - -u32 dt3155_setup_buffers(u32 *allocatorAddr); - -/* Get the next frame of data if it is ready. Returns */ -/* zero if no data is ready. If there is data but */ -/* the user has a locked buffer, it will unlock that */ -/* buffer and return it to the free list. */ - -int dt3155_get_ready_buffer(int minor); - -/* Return a locked buffer to the free list */ - -void dt3155_release_locked_buffer(int minor); - -/* Flush the buffer system */ -int dt3155_flush(int minor); - -/********************************** - * Simple array based que struct - **********************************/ - -bool are_empty_buffers(int minor); -void push_empty(int index, int minor); - -int pop_empty(int minor); - -bool is_ready_buf_empty(int minor); -bool is_ready_buf_full(int minor); - -void push_ready(int minor, int index); -int pop_ready(int minor); - - -#endif |